Compare commits

...

398 commits

Author SHA1 Message Date
569a77edf2
v1.8.3 2019-06-28 15:16:37 -06:00
91d8185ede
Updated startup scripts
* Moved starting apps from .update_x into .start_desktop_apps
  * This allowed .update_x to be shown on screen during startup
* Included "<Action>... Done" messages for clarity
* Removed x_ok logic (didn't really work)
  * Replaced with a generic message that _should_ be left on screen if X fails
2019-06-27 20:14:14 -06:00
18daa41e2a
Trimmed down motd 2019-06-27 20:13:09 -06:00
747277b121
Adjusted Super+t keyboard shortcut
* Now it opens to a standard urxvt window (no tmux attaching)
2019-06-27 20:11:02 -06:00
b8e09e83ce
Fixed issue #124 2019-06-27 18:57:45 -06:00
e798503f6f
Save RAM details to CpuObj 2019-06-12 16:37:04 -06:00
063ebc947e
v1.8.2 - Bugfix release
Linux
* Improved handling of tmux sessions
* Avoid crash in ddrescue-tui if LogDir is missing
* Avoid rare crash when uploading HW-Diag results for review

Windows Scripts
* Don't use MS Office formats in LibreOffice by default
* Restore default UAC during System Setup
2019-06-12 15:57:04 -06:00
5b5c99e6f8
Don't kill current tmux session from ddrescue-tui
* Just kill the panes and let launch-in-tmux handle the session
2019-06-12 15:48:11 -06:00
c50627867e
Switch to prev tmux from hw-diags & ddrescue-tui
* Only during normal exits, not done for aborts/crashes
2019-06-12 15:37:19 -06:00
e30e52e880
New launch-in-tmux script
* Generic run cmd in tmux wrapper
* ddrescue-tui and hw-diags source this script to run their respective menus
  * Reduces duplicate code
2019-06-12 15:31:30 -06:00
90f5285067
Updated tmux menu launchers
* Use current TMUX session if present
* Can switch TMUX session without nesting
* Fixes issue #114
2019-06-12 14:58:27 -06:00
441a6ad66f
Prevent ddrescue-tui crash when LogDir is missing
* Fixes issue #115
2019-06-12 14:05:45 -06:00
87668c6ad0
Avoid rare crash when uploading results for review
* Fixes issue #117
2019-06-11 20:52:45 -06:00
d1af82e114
Restore default UAC in System Setup
* Fixed mode names
* Fixes issue #119
2019-06-11 20:42:33 -06:00
dba39dd9c4
Don't use MS formats in LibreOffice by default 2019-06-11 20:32:30 -06:00
df5a3081b9
v1.8.1
Main Kit
* Added Win10 v1903 support
* System Setup script
  * Replaces Install SW Bundle, New System Setup, System Checklists, and User Checklists
  * Actions performed are based on the mode selected and answers given
  * Improved LibreOffice installations
    * Installed from a local source
    * Registers all MS Office types†
    * Sets default save-as options unless a config file is already present†
    * † Depending on setup mode selected
  * Improved performance when exporting system info
    * NOTE: Event logs are no longer saved
  * New 4K alignment check
  * New Win10 1903 theme handling
    * If updating Explorer (user) settings the Light theme is disabled
      * Set to the <= 1809 default to match Classic Start theme
* Fixed issue #102
* Various other bug fixes

Linux
* Auto-connects to known WiFi networks
* ddrescue-tui (AKA WKClone and WKImage)
  * Improved recovery state detection
    * NOTE: percentages may be off by 0.01% due to the rounding method used
* HW-Diagnostics
  * Added option to upload results for review
  * Added RAM info to CPU results screen
  * Added warning if one or more partitions are not 4K aligned
  * Improved AMD CPU support (k8, k10, etc)
  * Improved SMART detection and reporting
* New build-ufd script
  * Now written in Python
  * Only Linux (Full) is required, all other sources optional
  * Boot options are enabled based on files present on the UFD
  * Can update in place without reformatting
* Fixed issues #101-#108, & #113
* Various other bug fixes
2019-06-11 19:22:29 -06:00
eb3624e9ad
Integrated downstream updates
* Fixes issue #113
2019-06-11 18:55:23 -06:00
b95586a590
Moved to a unified system setup script
* Replaces:
  * Install SW Bundle
  * New System Setup
  * User Checklist
  * System Checklist
2019-06-11 18:42:31 -06:00
3007c22c41
Added Windows Update sections 2019-06-11 18:40:25 -06:00
f30d195cc4
Updated Explorer registry entries 2019-06-11 18:08:50 -06:00
c537a01fbf
Updated info.py 2019-06-11 17:55:50 -06:00
86f17757db
Updated cleanup sections 2019-06-11 17:49:10 -06:00
70823d2cd8
Updated HW-Diags and sensor sections 2019-06-04 20:53:34 -06:00
ec5591453e
Updated data.py 2019-06-04 20:16:09 -06:00
606efac3fe
Updated mounting sections 2019-06-04 20:09:56 -06:00
28bedc0873
Run ddrescue-tui as current user 2019-06-04 20:01:26 -06:00
52e4415b43
Updated ddrescue sections 2019-06-04 20:00:11 -06:00
248e321438
Updated windows_builds 2019-06-04 19:16:25 -06:00
c4ad9055d4
Launch Explorer windows in separate process 2019-06-04 19:14:36 -06:00
7a67e68308
Updated install_sw_bundle 2019-06-04 19:07:37 -06:00
434bb97765
Updated sw_diags.py 2019-06-04 19:01:21 -06:00
6a821de0b5
Added LibreOffice settings 2019-06-04 18:58:24 -06:00
576cb29281
Updated settings.setup.py 2019-06-04 18:57:07 -06:00
b83f2b0c5f
Updated pause() 2019-06-04 18:48:03 -06:00
2d3ccac369
Updated convert_to_bytes and human_readable_size 2019-06-04 18:46:35 -06:00
7816602685
4K Alignment checks 2019-06-04 18:40:42 -06:00
214df52723
Expanded SW bundle sections 2019-06-04 18:33:57 -06:00
35890d6bb3
Fixed setting timezone in Windows 2019-06-04 18:29:32 -06:00
7ccd4c6055
BITWISE operators =/= LOGICAL operators 2019-06-04 18:24:01 -06:00
5ccd628259
Updated check_disk.py 2019-06-04 17:10:38 -06:00
b9276aa0d7
Updated build-ufd 2019-06-04 17:09:59 -06:00
798876eb10
Updated UFD sections 2019-06-04 17:06:11 -06:00
617bb1484a
Name connections by SSID 2019-06-04 16:54:40 -06:00
d51538aac3
Fixed handling of known_networks 2019-06-04 16:52:17 -06:00
b554cfebe0
Update tmux config to work with v2.9 2019-05-08 19:38:48 -06:00
f8773e1736
Add known networks when building the Linux ISO
* Instead of at login
2019-05-05 12:53:07 -06:00
d8024be2c3
Add option to upload hw-diag results for review 2019-04-25 20:55:14 -07:00
dac20b12f1
Hide .bin and .cbin in build-ufd
* Fixes issue #107
2019-04-25 19:09:27 -07:00
5ae8ea3be1
Show more details for loopback devices
* Fixes issue #106
2019-04-25 19:05:44 -07:00
1d2d79eceb
Updated Rofi config
* Set font to Noto Sans
* Added HiDPI support
  * Fixes issue #105
2019-04-25 18:50:07 -07:00
896f9e4a05
Explicitly define smartctl tolerance levels
* Fixes issue #104
2019-04-25 18:37:17 -07:00
b737696f7f
Show more accurate data in mount-all-volumes()
* Fixes issue #108
2019-04-25 18:13:53 -07:00
2fb9b36959
Minor formatting change 2019-04-21 21:41:02 -07:00
5756d14292
Fix issue #102 2019-04-19 19:16:25 -07:00
2ce8c66fc8
Merge branch 'new-ufd-script' into dev 2019-04-19 19:03:29 -07:00
9502ea0bbc
Deleted old build-ufd (BASH) 2019-04-19 19:02:38 -07:00
8b4b0c40ce
Merge branch 'new-ufd-script' into dev 2019-04-19 19:01:56 -07:00
a83dcdd06a
Handle non-ISO source items 2019-04-19 18:14:10 -07:00
731a281805
More bugfixes 2019-04-19 16:33:12 -07:00
e2d788e265
Fixed upate_boot_entries() 2019-04-19 15:23:21 -07:00
0080539575
Copy the known_networks file to /root/ 2019-04-19 14:36:09 -07:00
19799bb1f4
Adjusting formatting 2019-04-18 20:52:47 -07:00
72c0e75156
Fix mounting UFD 2019-04-18 20:52:11 -07:00
27eb7975ef
Fixed SYSLINUX installation 2019-04-18 20:51:14 -07:00
b05057d743
Ignore errors when uncommenting boot entries
* Allows using older ISOs which lack newer boot entries
  * Not a great idea, but it won't crash
2019-04-18 20:00:37 -07:00
8edf164522
Avoid crash present in archiso v40-1
* Fix is present in upstream archiso-git
* iwd would be installed as a dependency for NetworkManager anyway
2019-04-18 19:29:40 -07:00
f062f3ce71
Fixed source ITEMS 2019-04-18 19:28:15 -07:00
153cda7cf8
Fixed update_boot_entries() 2019-04-18 19:27:41 -07:00
050bef7f85
Skip FileNotFoundError in copy_source()
* Avoids crash when copying some WinPE ISOs
2019-04-18 19:26:28 -07:00
e07c019fb2
Bugfix: Call unmount() not mount() 2019-04-18 19:25:13 -07:00
21a587ee0f
Bugfix sleep() 2019-04-18 19:24:39 -07:00
427243c933
Reordered functions 2019-04-16 00:33:47 -07:00
cd4ea75862
Remove the arch dir when updating the UFD 2019-04-16 00:23:58 -07:00
949efa4de6
Added hide items sections 2019-04-16 00:16:05 -07:00
a9461311bc
Unmount UFD before installing Syslinux 2019-04-16 00:15:33 -07:00
4215a2fd78
Added find_first_partition() 2019-04-16 00:14:46 -07:00
9652aa4623
Added install Syslinux section 2019-04-15 23:57:46 -07:00
091c31d33a
Bugfix 2019-04-15 23:52:06 -07:00
89ac824d82
Expanded boot entries sections
* Update Arch labels from ISO_LABEL to UFD_LABEL
* Added Linux (Minimal) to syslinux
* Added Linux (Minimal) and Linux (dGPU) entries to rEFInd
* Removed Linux (i3) entries
  * I guess this is a hidden feature now...
2019-04-15 23:44:42 -07:00
4115f3cfe1
Removed unused args 2019-04-15 23:16:57 -07:00
c66b2facbf
Skip confirm_selections if --force is used 2019-04-15 23:12:27 -07:00
c16e97e49a
Added boot entry sections 2019-04-15 23:07:33 -07:00
95f4877862
Reordered functions 2019-04-15 23:04:37 -07:00
fc9de61269
Added copy_source() 2019-04-15 22:40:20 -07:00
26aca0df9f
Added mount and unmount sections 2019-04-15 22:38:54 -07:00
7ee04060d8
Added dGPU to BOOT_ENTRIES 2019-04-15 22:37:58 -07:00
d769b1ad4e
Set overwrite=False by default 2019-04-15 22:05:48 -07:00
996b01bb34
Add Linux dGPU items 2019-04-15 21:30:44 -07:00
807c94e2ce
Add argument for Linux (dGPU) 2019-04-15 21:29:10 -07:00
af757c5582
Show full device paths 2019-04-15 21:28:53 -07:00
c8944e5a14
Fixed prep_device() 2019-04-15 21:27:27 -07:00
2230ea1eea
Added prep_device()
* Skipped if --update is used
2019-04-15 20:30:39 -07:00
e098d40c2f
Added pylint exceptions 2019-04-14 18:49:32 -07:00
72cc33cb7e
Only show destination device, not all devices 2019-04-14 18:48:54 -07:00
3310e3d253
Moved most logic to functions.ufd 2019-04-14 18:43:08 -07:00
164fd4c646
Fixed SystemExit calls from docopt 2019-04-14 18:09:36 -07:00
0e6be3ad08
Better SystemExit handling 2019-04-14 17:57:46 -07:00
1b312658e9
Fixed return code handling 2019-04-14 17:17:11 -07:00
cf1d11eb78
Always show header 2019-04-14 17:16:13 -07:00
cc1a318e3d
Abort if not running as root 2019-04-14 17:03:04 -07:00
6734460d42
Added option to skip pause in abort()
* Also use exit_script(1)
2019-04-14 17:01:53 -07:00
fde9be6b3f
Updated get_user_name() 2019-04-14 16:48:34 -07:00
d62a647fa9
Avoid setting LogDir to /root/Logs under su/sudo 2019-04-14 16:46:50 -07:00
5a1f7b1829
Silence build-ufd init 2019-04-14 15:58:09 -07:00
b2528b90f8
Fix docopt handling
* Show usage if invalid arguments are used
2019-04-11 22:25:13 -07:00
0883b099fd
Skip safety check if upgrading 2019-04-11 22:24:25 -07:00
23add7e276
Preserve DPI settings when updating conky 2019-04-11 21:40:51 -07:00
56ca605257
Regularly update conky config
* This should allow USB adapters to be shown if connected after login
2019-04-11 21:30:53 -07:00
c3ebdee5d0
Only update hostname when necessary
* If $IP was empty then HOSTNAME would remain set to the current HOSTNAME
  * This allowed the redundant set-hostname call
2019-04-11 21:14:32 -07:00
d113d710a7
Avoid dig errors if not connected to a network 2019-04-11 21:00:32 -07:00
c4755124a0
Remove more connect-to-network sections 2019-04-11 20:59:42 -07:00
ceb6a9e294
Use setup-wifi instead of connect-to-network 2019-04-11 20:57:30 -07:00
a8afd793e0
Added setup-wifi script
* This will replace the connect_to_network() function
2019-04-11 20:55:40 -07:00
d33f78960d
Reduced imports 2019-04-11 20:50:21 -07:00
1a8b6705e0
Show selections before starting work 2019-04-08 20:57:35 -07:00
415f56863d
Finished recursive_copy() 2019-04-08 20:26:41 -07:00
4d9ab2215b
Ensure SMART values are shown for some disks
* smartctl can return non-zero if there are errors in the SMART logs
2019-04-08 18:57:38 -07:00
14ebc23b81
Fix issue #101 2019-04-08 17:39:43 -07:00
b43309be75
Avoid rare crash when scanning CoreStorage volumes 2019-04-08 15:55:52 -07:00
8cdb834499
Initial, incomplete version of recursive_copy() 2019-04-08 02:59:03 -07:00
5fe37b62b2
Adjusted source/dest items 2019-04-08 02:58:07 -07:00
4c33c110b7
Fixed source validation 2019-04-08 00:35:53 -07:00
b166172d10
Only perform case-insensitive search if needed 2019-04-07 23:45:08 -07:00
e420074c83
Use correct errors in find_path()
* FileNotFoundError is accurate since we're just looking for a path
2019-04-07 23:35:00 -07:00
50cb765108
Merged find_source_item() and get_full_path()
* Also fixed regex match (it wasn't matching the whole string)
2019-04-07 23:26:22 -07:00
b6c6fc9aa9
Find paths case-insensitively 2019-04-07 22:44:15 -07:00
cd0a9456cb
Use pathlib.Path to resolve paths
* is_block_device() is no longer needed
  * (pathlib.Path provides that functionality)
2019-04-07 22:41:41 -07:00
c4d00a2073
Fix typos 2019-04-07 22:35:09 -07:00
575126eaa2
Split build-ufd file to match other scripts 2019-04-07 20:51:54 -07:00
3ff0bcd3c9
Updated new_system_setup.py to match other scripts
* i.e. don't change dir when setting sys.path
2019-04-07 19:07:31 -07:00
639a338cca
Initial Python layout
* Going to use docopt for argument handling
* Script will be run as user using sudo where needed
* Tentatively dropping tmux usage
2019-04-07 19:03:56 -07:00
a22e6f552f
Start build-ufd rewrite in python 2019-04-07 19:01:03 -07:00
e1cfe6d2d3
v1.8.0
Main Kit
* Adjust Windows Update settings during System Checklist and New System Setup
* Restart Explorer after adjusting settings to show them immediately
* Show warning if Python can't be run and how to fix it
* Fixes issues #91, #93, & #97
* Various other bug fixes

Linux
* Major upgrades to Hardware Diagnostics
  * Prime95 testing will auto-abort if a specified thermal limit is reached
  * NVMe / SMART is rechecked after all disk tests have been performed
    * This more acurately report data if other tests run into an error
  * Improved SMART short self-test support
  * Support running badblocks on disks over 4TB
* Show estimated completion time in ddrescue-tui
* Added ldmtool to support reading MS Dynamic volumes
* Fixed issues #58, #88, #89, #90, #92, #94, #95, #96, #99, & #100
* Various other bug fixes

Misc
* Improved build-ufd script
  * Find and copy WinPE files case-insensitively
  * Better logging
* Moved script settings to separate files
  * For easier configuration
2019-04-03 13:08:24 -07:00
e089dd99a3
Avoid crash when no disks are connected
* It was attempting to recheck the NVMe/SMART data for the fake N/A lines
2019-04-02 16:29:09 -07:00
52e3e24a3a
Updated build-ufd 2019-03-30 09:48:48 -07:00
c5364a65a2
Avoid copying the wrong files from WinPE
* if w_en_us was empty it would copy the contents from $(pwd)
2019-03-30 09:45:36 -07:00
0b31fa271d
Expand build-ufd log 2019-03-30 09:38:13 -07:00
c022d3f9c6
Set ddrescue-tui EToC refresh rate in settings 2019-03-20 15:48:01 -06:00
28cea9697e
Moved ddrescue-tui EToC code to its own function
* Limited refresh rate to every 5 seconds
2019-03-20 15:45:27 -06:00
fa05c93bf8
Added EToC line to ddrescue-tui side-pane
* Is not shown in main menu
2019-03-20 15:21:19 -06:00
c96ffc5f59
Added overall status line to ddrescue-tui 2019-03-20 13:16:09 -06:00
95338f1df7
Add encoding to run_program and popen_program 2019-03-20 12:57:56 -06:00
877db91cb6
Extended Windows build list 2019-03-19 20:45:37 -06:00
826edc0c33
Extended Windows build list 2019-03-19 20:41:51 -06:00
723f1ad4ad
Fixed WizTree extraction 2019-03-19 14:16:39 -06:00
089cdba4f9
Updated sources 2019-03-19 14:16:16 -06:00
f98c106080
Bugfix: Extremely minor formatting issue 2019-03-17 21:30:25 -06:00
48c0cf0b1b
Adjusted Explorer settings 2019-03-17 20:43:19 -06:00
4cb14c6429
Restart Explorer after configuring
* Allows changes to be seen without restarting manually
2019-03-17 20:23:25 -06:00
b84d4eb6b8
Bugfix: typo 2019-03-17 20:22:50 -06:00
1235269da0
Bugfix 2019-03-17 20:17:00 -06:00
2e679dbf5e
Download stand alone Windows update installers
* Fixes issue #91 (again)
2019-03-17 18:11:36 -06:00
84deb49beb
Explicitly set colors to properly reset errorlevel 2019-03-16 23:03:13 -06:00
ec74b06282
Verify Python can be run before launching script
* Fixes issue #91
2019-03-16 23:02:44 -06:00
f9b35b9a3d
Fixed dict collision
* Fixes issue #97
2019-03-16 18:14:31 -06:00
c5b4446133
Configure Windows Updates during checklist/setup
* Sets readiness branch to non-targeted semi-annual
* Defers feature upgrades for 60 days
* Fixes issue #93
2019-03-16 18:11:19 -06:00
86f81f2720
Prevent updating OVERRIDE to CS 2019-03-16 15:11:42 -06:00
70b8d2536a
Missed a functions/json.py import 2019-03-13 20:39:47 -06:00
34ef0bfae6
Fail test on SMART self-test timeout 2019-03-13 20:22:28 -06:00
648787913e
Fixed issues importing settings files 2019-03-13 19:02:35 -06:00
75df9777b3
Removed extraneous whitespace 2019-03-12 22:49:25 -06:00
122bbfb157
Added debug mode for HW Diagnostics
* Uses alternative major exception
  * Saves State, CpuObj, and DiskObj data after traceback
  * Uploads the whole LogDir folder (compressed) instead of just the main log
2019-03-12 21:24:06 -06:00
7381547b27
Added functions.json
* Uses safer method to get JSON data from a command
* Replaced nearly all uses of json.loads with new get_json_from_command()
* Fixes issue #100
2019-03-12 16:08:21 -06:00
480222c1f2
Adjusted variable name usage for consistency 2019-03-12 15:13:16 -06:00
3fa6521c51
Only enable WinPE boot entries if necessary
* Addresses issue #94
2019-03-11 22:31:56 -06:00
459f95394a
Allow building UFD with only the Linux ISO
* Addresses issue #94
2019-03-11 22:27:07 -06:00
22b1452168
Find WinPE sources case-insensitively
* Allows non-WK WinPE builds to be used
* Addresses issue #94
2019-03-11 22:24:11 -06:00
1d10503b91
Support disks over 4TB in badblocks test
* Set read block size to 4KB if disk is 4Kn or 3TB+
* Fixes issue #99
2019-03-11 21:00:26 -06:00
e7d31c21c3
Get disk size in bytes during object creation
* Also moved dd calc section into docstring
2019-03-11 20:55:24 -06:00
7f6509d235
Return to HW-Diags menu from safety_check() 2019-03-11 13:26:11 -06:00
7701418e55
Recheck disk attributes after all tests
* Should catch errors exposed by badblocks
* Addresses issue #96
2019-03-11 13:25:12 -06:00
7078efe9e7
Adjusted SMART self-test running message 2019-03-11 13:23:56 -06:00
a3d2de92bc
Show CS/NS in quick mode if self-test is running
* It still shows the slightly ambiguous message "all tests disabled"
* Addresses issue #96
2019-03-11 12:37:01 -06:00
607d4b1e57
Skip SMART self-test in quick mode
* Addresses issue #96
2019-03-11 12:36:33 -06:00
6edfcc9766
Moved SMART self-test code to its own function
* Allows for a simpler run_nvme_smart_tests()
* Self-test is now done before the attribute check
* Addresses issue #96
2019-03-11 11:57:29 -06:00
40f269aabd
More cleanup for generate_attribute_report() 2019-03-11 10:52:11 -06:00
a5852d1caa
Major overhaul of NVMe/SMART reporting/testing
* Moved all errors/warnings to new nvme_smart_notes var
  * Allows the notes to be appended to the attribute report much easier
  * Allows the attribute report to be updated without losing notes
* NVMe/SMART should only contains the SMART short self-test results
  * If available and requested
* Updated safety_check to fix erroneous requests
  * Disable tests logic reworked
* Updated generate_disk_report() to include notes
* Addresses issue #96
2019-03-09 21:42:28 -07:00
95aa063a69
Adjusted disk safety checks
* check_attributes() is now always silent
  * Returns a PASS/FAIL bool
  * override_disabled is now at the Disk() scope
* Moved self-test checks to check_smart_self_test()
  * Returns a PASS/FAIL bool
* Addressed issue #96
2019-03-09 18:07:04 -07:00
e60bfaca48
Show better errors while building Linux
* Addresses issue #58
2019-03-09 14:27:23 -07:00
858c2e1bd5
Avoid crash on some Macs
* Partially addresses issue #88
  * HW damage should be avoided by using the THERMAL_LIMIT setting
2019-03-09 14:15:42 -07:00
b0e2b01e00
Added beep function
* Fixes issue #89
2019-03-09 14:11:53 -07:00
d5dc453ffa
Added maximum threshold for NVMe/SMART attributes
* Fixes issue #95
2019-03-05 19:36:43 -07:00
68a3b6d0c7
Fixed REGEX sections in settings files 2019-03-05 19:36:42 -07:00
197a5a9160
Misc cleanup 2019-03-05 19:36:42 -07:00
62f2ec8a4d
Moved SW-Diags settings to separate file 2019-03-05 19:36:42 -07:00
4197fc9e0b
Moved WinPE settings to separate file 2019-03-05 19:36:42 -07:00
8d8399c9aa
Moved windows setup settings to separate file 2019-03-05 19:36:42 -07:00
af5281626b
Moved setup settings to separate file 2019-03-05 19:36:42 -07:00
8add6f634c
Moved sensor settings to separate file 2019-03-05 19:36:41 -07:00
058a52961d
Moved info settings to separate file 2019-03-05 19:36:41 -07:00
d03772666d
Moved ddrescue-tui settings to separate file 2019-03-05 19:36:41 -07:00
974e20df05
Moved data settings to separate file 2019-03-05 19:36:41 -07:00
34f4bca97d
Moved browser settings to separate file 2019-03-05 19:36:41 -07:00
e2c83aad6e
Moves HW-Diags settings to separate file 2019-03-05 19:36:41 -07:00
cd4bb7c867
Create launcher for new_system_setup.py 2019-03-05 16:34:13 -07:00
0398ea7e51
Disable Tips & Tricks (more) 2019-02-27 23:57:13 -07:00
fa2aa04b53
Forgot dependencies for ldmtool 2019-02-05 23:02:23 -07:00
27eb984e73
Add ldmtool to read MS dynamic volumes
Fixes issue #92
2019-02-05 22:24:48 -07:00
017c0e3385
Avoid marking aborted badblocks test as failed 2019-02-05 21:49:00 -07:00
82377bc1ab
Stop Prime95 if CoreTemps hit 95*C
Fixes issue #90
2019-02-05 21:34:47 -07:00
7132d971f6
Add temp limit to report 2019-02-05 21:26:27 -07:00
dc6de9cab0
Use consistent labels 2019-02-05 21:25:28 -07:00
a28a754be1
Added thermal limit logic to Prime95 test 2019-02-05 21:08:06 -07:00
3c35a75c92
Raise exception when temps >= limit 2019-02-05 21:06:40 -07:00
f8404f3c16
Raise exception if temps above given threshold 2019-02-05 20:31:16 -07:00
56fa227686
v1.7.1 - Another World (bugfix) 2019-01-15 23:13:40 -07:00
5efdf05274
Adjusted VIM settings 2019-01-15 19:06:56 -07:00
7c7d8e41e2
Prevent crash when testing some NVMe disks 2019-01-15 18:56:29 -07:00
046208cfb6
v1.7.0
Main Kit
* Updated tool versions
  * Added MS Office 2019 installers
  * Removed network installers
* Added "New System Setup" script
  * Combines "Install SW Bundle", "User Checklist", & "System Checklist"
* Added Windows 1809 build numbers
* Fixed issues #86 & #87
* Various other minor bug fixes

Linux
* Complete rewrite of HW Diagnostic sections
  * New main menu to improve clarity of selections
  * Allow overriding non-critical SMART attributes
    * NOTE: This doesn't apply to a full (disk) diagnostic
  * All tests can now be aborted with CTRL+c
  * Tmux panes are now resized appropriately if the window is resized
  * Various other enhancements and bugfixes
* Complete rewrite of HW Sensors sections
  * Temps are now tracked directly allowing for real "Max" values
* ddrescue-tui
  * Added safety check to ensure the map file is saved to persistent storage
  * Tmux panes are now resized appropriately if the window is resized
  * Added 'DDRESCUE PROCESS HALTED' message in red
    * Used to clearly indicate that user interaction is required
* If X fails to start it will fallback to HW-Diags CLI
* Added option to build Linux with a minimal package set
  * This is to better support newer Mac systems
  * This version includes additional Mac kernel modules
  * NOTE: Minimal builds are still considered experimental
* Fixed issues:
  * #67, #68, #69, #70, #71, #72, #73, #74, #75
  * #76, #77, #78, #80, #81, #82, #83, #84, & #85
* Various other minor bug fixes

Misc
* Updated all Python code to better follow to PEP8 guidelines
* Updated crash upload formatting for clarity
2019-01-14 15:22:50 -07:00
814ada0ac0
Updated HWiNFO url 2019-01-13 17:59:06 -07:00
fcd8d67f51
Bumped year in LICENSE.txt 2019-01-13 14:52:31 -07:00
5b9e91f8af
Updated Killer Network drivers source 2019-01-13 14:51:53 -07:00
bece9837b2
Moved Office 2019 installers to their own folder 2019-01-11 14:42:18 -07:00
6c47650c2d
Updated IOBit Uninstaller 2019-01-11 14:18:01 -07:00
fd8358a899
Fix ODT path 2019-01-11 14:17:41 -07:00
cb072366e0
Bugfix Office sections
* Addresses issue #86
2019-01-11 13:25:33 -07:00
4a96736592
Removed network installers 2019-01-11 13:17:25 -07:00
ad1d7d71f2
Fixed ODT sections
* Fixes issue #86
2019-01-11 12:59:12 -07:00
6246393894
Fixed update_fastcopy() 2019-01-11 12:31:08 -07:00
c1324548ce
Track ninite processes directly 2019-01-09 20:59:21 -07:00
969011f3f5
Added new_system_setup() 2019-01-09 20:55:48 -07:00
6488101cdc
Dumb workaround for Dell sensors 2019-01-09 16:29:18 -07:00
e088ba134e
Tool version bumps 2019-01-08 23:48:50 -07:00
f2bd2a6e75
Adjusted global_vars report 2019-01-08 20:33:23 -07:00
6ea4791dc9
Added generate_global_vars_report()
* Makes crash reports more readable
2019-01-08 20:24:43 -07:00
63f9c1c193
Fixed set_log_file() under Linux 2019-01-08 20:24:14 -07:00
ed70d1ab18
Simplified tmux repair thread handling
* Just start once and let run until script is exited
* Pretty sure this fixed the 100%+ CPU usage after returning to the menu
2019-01-08 19:18:00 -07:00
f8adbe074d
Added Linux headers for macbook12-spi-driver-dkms
* Addresses issue #67
2019-01-07 16:17:37 -07:00
4bd0cd1598
Avoid crash when no sensor data available
* This was broken when fixing issue #85
2019-01-07 15:29:33 -07:00
beb36dfc97
Adjusted window name 2019-01-07 12:54:28 -07:00
ebcd38ef50
Don't change directory during initialization
* Fixes issue with ddrescue-tui
2019-01-07 12:53:23 -07:00
ae92eea76e
Added macbook12-spi-driver-dkms to Minimal build 2019-01-06 22:43:33 -07:00
50da682d76
Fix issue #85 2019-01-06 22:12:01 -07:00
7a9474a6a8
Try enabling SMART before checking attributes
* Fixes issue #84
2019-01-06 21:51:45 -07:00
68bbee66d5
Replaced hw-diags-badblocks with threaded section
* Should fix issue #83
2019-01-06 21:45:01 -07:00
e40b0b98e4
Moved fix_tmux_panes() into a background thread 2019-01-06 20:57:06 -07:00
4a04e92caf
Added threading.py
* Will be used by hw_diags.py and ddrescue.py for
  * Better control over badblocks
  * Background the tmux pane fixes
2019-01-05 15:54:05 -07:00
aa4c6a1434
Fix issue #82 2019-01-02 18:04:32 -07:00
3d69fe773d
Removed sensors section from hw-info
* Fixes issue #81
2019-01-02 18:02:24 -07:00
141fe422db
Fix NVMe attribute handling
* Addresses issue #78
2019-01-02 17:55:56 -07:00
3122a75f64
Skip fan RPMs
* Avoids reporting fan RPMs as 6000+ *C
2019-01-02 17:31:19 -07:00
6340bceb11
Added warning if no disks detected. 2019-01-02 17:05:08 -07:00
a9c5c1c274
Fixed issue #80 2018-12-28 17:46:02 -07:00
8f9bae9a6f
Added option to build Linux with minimal packages
* All non-minimal packages/configs have been separated from the base setup
* `"Build Linux" -b` will only build the full version
2018-12-28 16:51:15 -07:00
575fa17425
Only use Unicode checkmark if in X 2018-12-28 15:44:14 -07:00
91649f5ee7
Removed args from run_program
* It's been deprecated for ages
* Fixes issue #79
2018-12-27 23:43:35 -07:00
1095e15643
More PEP8 updates 2018-12-27 22:52:50 -07:00
453ce9cf44
More fixes for main.py 2018-12-27 22:48:20 -07:00
b6e9e447c5
Fixed main.py 2018-12-27 22:45:49 -07:00
6df88ec021
Updated settings files 2018-12-27 22:42:42 -07:00
f321dee54f
Switched indents to 2 spaces 2018-12-27 22:28:17 -07:00
3e733e65e9
Updated network.py 2018-12-27 22:17:23 -07:00
7b8b1ab111
Updated files to meet PEP8 guidelines
* Fixes issue #42
  * More work is likely needed
2018-12-27 21:46:04 -07:00
922d632afb
Removed trailing whitespace 2018-12-27 21:44:46 -07:00
5af0996259
Removed whitespace on empty lines 2018-12-27 21:42:00 -07:00
c96e2f252c
Cleaned up imports 2018-12-27 21:38:25 -07:00
d0c49240d8
Added extra line break after classes/functions/etc
* Also reordered some class/regex/static sections
2018-12-27 21:33:37 -07:00
3b4668e61b
Adjusted init section 2018-12-27 21:02:04 -07:00
c7706a115f
Updated hw-diags-network 2018-12-27 20:58:37 -07:00
b1786e088c
Updated hw-diags-audio 2018-12-27 20:58:26 -07:00
c501c8b23f
Updated docstrings longer than 72 characters 2018-12-27 20:51:56 -07:00
387062074a
Updated msword-search 2018-12-27 20:30:40 -07:00
4ddce7cfbe
Updated mount-backup-shares 2018-12-27 20:28:26 -07:00
a9ebeee748
Updated mount-all-volumes 2018-12-27 20:28:14 -07:00
25bacb9892
Updated ddrescue-tui-menu 2018-12-27 20:27:55 -07:00
5664765f6e
Updated connect-to-network 2018-12-27 20:27:44 -07:00
c3ca58879c
Updated winpe_menus.py 2018-12-27 20:15:02 -07:00
ec0341027e
Updated windows_setup.py 2018-12-27 20:14:29 -07:00
fa424a4576
Updated update.py 2018-12-27 20:13:32 -07:00
a47707447c
Updated setup.py 2018-12-27 20:10:49 -07:00
cfd4eebcd4
Updated safemode.py 2018-12-27 20:09:26 -07:00
deb9d9add1
Updated repairs.py 2018-12-27 20:08:56 -07:00
82a2d6b74d
Updated product_keys.py 2018-12-27 20:07:18 -07:00
72eac47524
Updated disk.py 2018-12-27 20:05:53 -07:00
07e43307c5
Moved partiton_uids.py to settings 2018-12-27 20:04:29 -07:00
018aba2fe6
Updated network.py 2018-12-27 19:58:06 -07:00
097fae866a
Updated info.py 2018-12-27 19:57:39 -07:00
166a293864
Updated hw_diags.py 2018-12-27 19:55:41 -07:00
ffd07e07fd
Renamed diags.py to sw_diags.py
* Avoid confusion with hw_diags.py
2018-12-27 19:53:58 -07:00
0a899539c9
Updated diags.py 2018-12-27 19:52:18 -07:00
10e978d4c5
Updated ddrescue.py 2018-12-27 19:50:51 -07:00
4049272cbb
Updated data.py 2018-12-27 19:48:32 -07:00
c74e2c7667
Updated common.py 2018-12-27 19:43:37 -07:00
327c5b8a33
Updated cleanup.py 2018-12-27 19:43:25 -07:00
6a3e225192
Updated browsers.py 2018-12-27 19:43:12 -07:00
a269859b17
Updated backup.py 2018-12-27 19:42:58 -07:00
36e419bca0
Updated activation.py 2018-12-27 19:42:28 -07:00
765673db66
Updated windows_builds.py 2018-12-27 18:06:59 -07:00
28e2ce90df
Removed nvme-cli in favor of smartctl 2018-12-27 18:03:16 -07:00
a124236def
Removed unused pydf config 2018-12-27 18:01:42 -07:00
4b956d5eea
Fix MemTest86 extraction 2018-12-27 17:51:51 -07:00
a39c62eabc
Fix crash if no sensors available 2018-12-27 17:47:01 -07:00
dcc2e5cd6a
Adjusted top pane text 2018-12-26 21:00:29 -07:00
98c0c34bf8
Removed unused vertical_graph data 2018-12-26 17:11:37 -07:00
96d34ceb50
Fix SMART short-test results section
* OVERRIDE status reduced to yellow/warning
  * Allows it to be elevated to NS or TimedOut
* Only disable other disk tests on test.failed
  * OVERRIDE doesn't work if based on test.passed for this test
2018-12-23 17:33:16 -07:00
6e37736146
Only save attributes to log during show_results() 2018-12-23 17:15:50 -07:00
c15eb85a5e
Removed unused get_status_color and Skipped status 2018-12-22 18:07:06 -07:00
6d9f50629c
Reworked status/color sections 2018-12-22 17:55:49 -07:00
d37923a31c
Bugfix: typo 2018-12-20 17:26:27 -07:00
d930bdddbd
Zero beginning of UFD before formatting
* Fixes issue #68
2018-12-20 16:10:08 -07:00
d60aab9584
Updated MemTest86 to 8.0
* Passmark is no longer providing ISOs so the UFD image is used instead
* This is an alternative solution to issue #71
2018-12-20 16:03:54 -07:00
eed8a1e40c
Fix poweroff/reboot calls 2018-12-20 15:25:39 -07:00
c6eb7cdfd6
Use new arguments when calling hw-diags 2018-12-19 18:53:13 -07:00
f022d0ca76
Fallback to HW-Diags CLI if X fails to start
* Fixes issue #74
2018-12-19 18:45:58 -07:00
42407f0eca
Adjusted ddrescue exit handling
* Wait for ddrescue_proc after KeyboardInterrupt
  * ddrescue prints extra info to the screen after a CTRL+c
* Explicitly mark KeyboardInterrupt events as an abort
* Add 'DDRESCUE PROCESS HALTED' message in red if exiting non-zero
  * More clearly indicates that user interaction is required
  * Fixes issue #72
2018-12-18 20:35:21 -07:00
44fe888230
Replaced ddrescue-tui-smart-display
* Output data to file and have tmux pane watching said file
* This method handles resizing much better
2018-12-18 20:15:35 -07:00
62b8e51705
Updated ddrescue-tui tmux pane size handling 2018-12-18 19:45:02 -07:00
ad15cdad56
Added warning if not saving map to a preferred FS
* Fixes #76
2018-12-18 17:28:06 -07:00
04cfdff2bf
Don't show init, just disk details 2018-12-18 17:27:15 -07:00
e1834d5179
Added silent mode to init_global_vars() 2018-12-18 17:26:20 -07:00
ad9662c120
Updated to use new hw_diags.py 2018-12-18 16:38:40 -07:00
fad65b8df6
Merge branch 'hw-diags-rewrite' into dev 2018-12-18 16:10:34 -07:00
e5f0ccb5d5
Formatting cleanup 2018-12-18 15:57:48 -07:00
91a77bb14e
Ensure SMART timeout message is in the report 2018-12-18 15:47:03 -07:00
7ac035c578
Safety wheels off 2018-12-18 15:21:05 -07:00
932669844b
Fixed tmux pane size handling 2018-12-18 15:13:33 -07:00
10ae59be19
Update tmux layout periodically 2018-12-18 00:55:57 -07:00
0c0f8e8950
Added disable_test() to Disk class 2018-12-17 20:51:02 -07:00
41c9a4d23f
Fixed only showing non-empty graph lines 2018-12-17 20:29:09 -07:00
8c5820d5aa
Fix horizontal graph
* generate_horizontal_graph() now returns a list instead of a str
2018-12-17 20:16:35 -07:00
ec8c78197b
I/O Benchmark test is working 2018-12-17 20:15:40 -07:00
385bdd7dbf
Allow resizing current pane 2018-12-17 20:10:58 -07:00
a25a10e616
More abort logic updates 2018-12-17 14:07:19 -07:00
c820d2ac6d
Fixed Prime95 abort handling 2018-12-17 13:20:39 -07:00
baaf1994e3
Catch keyboard interrupt and gracefully abort 2018-12-16 22:44:46 -07:00
e0a2993c36
Skip disk safety checks if only testing the CPU 2018-12-16 22:18:34 -07:00
d8123a71ec
Renamed generate_report to generate_sensor_report 2018-12-16 22:07:34 -07:00
4c0bb1c9b7
Group results by device instead of test 2018-12-16 22:06:03 -07:00
503e6f2b42
Fix SMART short-test timeout detection 2018-12-16 19:45:25 -07:00
a4896a55f6
Adjust log names 2018-12-16 19:31:34 -07:00
8993b483a6
Fix bad cable note 2018-12-16 19:30:46 -07:00
ef42b596d9
Catch CTRL+c aborts and show results 2018-12-15 18:56:41 -07:00
8b936f5413
badblocks section working 2018-12-15 18:45:43 -07:00
e96ac5c156
Added watch option to use tail instead of cat
* tail -f acurately prints backspace (^H) characters
  * badblocks output uses them and wouldn't work with watch/cat
2018-12-15 18:09:54 -07:00
dc8416b5f7
Adjusted formatting 2018-12-15 16:55:32 -07:00
a5d92537f5
Removed unused function 2018-12-15 16:54:48 -07:00
f2a519b7ec
Adjusted log and results screen 2018-12-14 18:58:32 -07:00
37b8676b9c
Fixed quick check 2018-12-14 18:57:30 -07:00
99984603ed
NVMe/SMART sections working
* Added timout status for clarity
* Added short-test result to report
2018-12-14 18:32:17 -07:00
cee8252455
Added CYAN to COLORS 2018-12-14 18:03:00 -07:00
81f05fa79f
Replaced show_attributes() with generate_report()
* Returns list of colored strings
* Optionally includes short-test results
* Optionally excludes disk info
2018-12-14 16:37:14 -07:00
5b74879805
Fixed OVERRIDE and N/A NVMe/SMART status handling 2018-12-13 19:02:28 -07:00
b5c93317dc
Override sections working 2018-12-11 23:54:02 -07:00
47084efe17
Combined nvme_check() and smart_check() 2018-12-11 23:18:51 -07:00
62a60ff3fd
Reworked disk safety checks
* Moved several functions into DiskObj
* Added HW_OVERRIDES_FORCED and HW_OVERRIDES_LIMITED to main.py
  * These adjust when overrides are requested
* Disable badblocks and/or io_benchmark if disk fails safety check
2018-12-11 22:56:09 -07:00
a967a5c425
Switched back to int keys for SMART attributes
* Allows for easier sorting
2018-12-11 20:40:57 -07:00
a3f7e5ad89
Disk quick check almost done 2018-12-11 00:54:16 -07:00
6c06a67fdf
Prime95 section complete 2018-12-10 22:54:56 -07:00
d9554314d5
Updated run_program() and popen_program()
* Use dicts for clarity
* Support cwd flag
2018-12-10 19:42:10 -07:00
a2ef06e6db
Added strip_colors() function 2018-12-10 19:19:35 -07:00
2b43cdf9e2
Create watch file if it doesn't exist yet 2018-12-10 19:19:11 -07:00
30d4acd986
Added watch mode to respawn-pane 2018-12-10 19:18:16 -07:00
8a8a63eb66
Build Prime95 report 2018-12-10 19:16:43 -07:00
a00105f718
Fixed status updates 2018-12-10 16:57:43 -07:00
bb93386fa0
Updated Prime95 checks 2018-12-10 16:32:00 -07:00
465a3b42fb
Kill all tmux panes before exiting 2018-12-08 18:36:50 -07:00
d88a9f39f2
Added tmux_kill_all_panes() 2018-12-08 18:36:24 -07:00
668c7c4c6a
Updated run_mprime_test to use test_obj 2018-12-08 18:32:03 -07:00
941a553766
Renamed "Prime95 & Temps" to "Prime95" for brevity 2018-12-08 18:16:31 -07:00
49471663f5
Use OrderedDicts to avoid lambda sorting 2018-12-08 17:50:11 -07:00
0390290f10
Added TestObj()
* This object will track test specific vars and results
  * Moved status code into TestObj
  * Test calls will now be: run_test(state, dev, test_obj)
* NOTE: Code is not done and is quite broken
2018-12-08 17:46:17 -07:00
6a3ef60881
Added CpuObj and renamed dev names to disk
* This should make the code more clear
* The CpuObj is similar to DiskObj to abstract the device/tests calls
  * New calls will be like: run_test(state, dev)
2018-12-08 17:41:29 -07:00
12ff99eb32
Set LogDir for non-quick tests 2018-12-06 18:27:43 -07:00
a910f2cb03
Adjusted Prime95 countdown 2018-12-06 18:27:19 -07:00
ca4234b1c3
Added working_dir arg for tmux command sections 2018-12-06 15:29:06 -07:00
dc606a8780
Main Prime95 sections working
* Still need check results and update progress sections
2018-12-06 01:06:21 -07:00
30ba651674
Removing report wrapping section
* Doesn't work properly with background processes
2018-12-06 00:10:51 -07:00
74bb31e795
Open temps monitor during run_mprime 2018-12-05 23:57:38 -07:00
5550cce8db
Add background mode for monitoring sensors
* This will be called by hw_diags.py to update a file in the background
* NOTE: This uses a naive check before attempting to write data
2018-12-05 23:55:15 -07:00
c777d49091
Added tmux_resize_pane() 2018-12-05 23:54:37 -07:00
5405b97eb1
Standalone sensor monitor working again 2018-12-05 23:09:42 -07:00
46080b4363
Moved tmux sections to separate file 2018-12-05 22:25:44 -07:00
0e5fab0104
Handle missing labels in generate_report() 2018-12-05 21:57:55 -07:00
95b0d1e3f4
Wrap reports if necessary 2018-12-05 21:54:41 -07:00
328d6eb294
Modify sensor_data in place 2018-12-05 20:47:40 -07:00
2eccc236a9
Added generate_report()
* Also merged save_max_temp() with update_sensor_data()
  * Max doesn't need resetting so just calc max everytime
2018-12-05 20:40:25 -07:00
7140f38ba4
Added average, clear, and max temps sections 2018-12-05 20:11:10 -07:00
cb67f7e3c3
Added new sensors.py and dropped borrowed sensors 2018-12-05 19:59:41 -07:00
5dd8fa8416
Get CPU details from lscpu 2018-12-05 17:48:30 -07:00
163f64dda7
Reduced timeout for major exceptions 2018-12-05 04:10:20 -07:00
372f80bf38
Skip optical drives 2018-12-05 04:08:59 -07:00
7c163a8110
Added update progress sections 2018-12-05 03:52:24 -07:00
d025b8dc9e
Adjusted how devices are added to the state obj
* The change allows for devices to be (dis)connected while the script is running
  * Devices are scanned and added during run_hw_diags()
* Fixes bug that prevented any devices from being added as well
2018-12-05 03:49:25 -07:00
2d69d93154
Added watch option for tmux_split_window() 2018-12-05 03:41:27 -07:00
43b9645c69
Update tmux panes via respawn-pane
Instead of send-keys
* Avoids flooding zsh history
* Less flickering
2018-12-04 23:39:15 -07:00
4bb1402ac5
Added tmux functions
* Going to try and replace the send-keys sections next
2018-12-04 20:50:47 -07:00
8fb1620c94
Added placeholder functions for HW tests 2018-12-04 19:23:35 -07:00
597a236089
Don't clear screen twice at startup
* Combined init_global_vars and add_devs output
2018-12-04 18:44:52 -07:00
1489ad4237
Added safety check for devices 2018-12-04 18:43:50 -07:00
62c9d82fd2
Adjusted placeholders 2018-12-04 17:05:53 -07:00
5701b53026
Added --quick argument to skip menu 2018-12-04 16:55:17 -07:00
6014a8fb70
Don't add WK or loopback devices 2018-12-04 16:18:45 -07:00
70a742e69c
Add device details from lsblk
* Also ensure sane types for some attributes
2018-12-04 16:10:58 -07:00
2df4d48bb3
Show selected tests on run 2018-12-03 20:15:56 -07:00
560929e2fa
Removed extra line break in menu_select 2018-12-03 19:54:06 -07:00
18fc97293e
Renamed Drive to Disk to align options in menu 2018-12-03 19:50:55 -07:00
3fdd8c629c
Rewrote main menu
* First options are presets followed by individual tests
* Selecting presets will toggle the selections
* Screensavers are hidden but still present
2018-12-03 19:47:44 -07:00
10f2fca2bf
Added classes DevObj and State 2018-12-03 17:52:07 -07:00
153 changed files with 14084 additions and 11052 deletions

View file

@ -151,6 +151,7 @@ goto Exit
call "%bin%\Scripts\init_client_dir.cmd" /Office
set "_odt=False"
if %L_PATH% equ 2016 (set "_odt=True")
if %L_PATH% equ 2019 (set "_odt=True")
if "%_odt%" == "True" (
goto LaunchOfficeODT
) else (
@ -161,8 +162,8 @@ if "%_odt%" == "True" (
rem Prep
set "args=-aoa -bso0 -bse0 -bsp0 -p%ARCHIVE_PASSWORD%"
set "config=%L_ITEM%"
set "dest=%client_dir%\Office\%L_PATH%"
set "odt_exe=%L_PATH%\setup.exe"
set "dest=%client_dir%\Office\ODT"
set "odt_exe=setup.exe"
set "source=%cbin%\_Office.7z"
rem Extract
@ -262,6 +263,7 @@ call :ExtractOrFindPath || goto ErrorProgramNotFound
set "script=%_path%\%L_ITEM%"
rem Verify
"%PYTHON%" --version >nul || goto ErrorPythonUnsupported
if not exist "%script%" goto ErrorScriptNotFound
rem Run
@ -434,6 +436,16 @@ echo ERROR: Office version not supported by this script.
start "" "explorer.exe" "%client_dir%\Office"
goto Abort
:ErrorPythonUnsupported
rem The Windows installation lacks Windows update KB2999226 needed to run Python
echo.
echo ERROR: Failed to run Python, try installing Windows update KB2999226.
echo NOTE: That update is from October 2015 so this system is SEVERELY outdated
if exist "%bin%\..\Installers\Extras\Windows Updates" (
start "" "explorer.exe" "%bin%\..\Installers\Extras\Windows Updates"
)
goto Abort
:ErrorQuickBooksSourceNotFound
echo.
echo ERROR: QuickBooks source "%L_ITEM%" not found.
@ -485,7 +497,7 @@ echo Press any key to exit...
pause>nul
rem reset color and reset errorlevel to 0
rem NOTE: This is done to avoid causing a ErrorLaunchCMD in the launcher.cmd
color
color 07
goto Exit
:: Cleanup and exit ::

View file

@ -4,59 +4,60 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.activation import *
init_global_vars()
os.system('title {}: Windows Activation Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: Windows Activation Tool\n'.format(KIT_NAME_FULL))
# Bail early if already activated
if windows_is_activated():
print_info('This system is already activated')
sleep(5)
exit_script()
other_results = {
'Error': {
'BIOSKeyNotFoundError': 'BIOS key not found.',
}}
try:
stay_awake()
clear_screen()
print_info('{}: Windows Activation Tool\n'.format(KIT_NAME_FULL))
# Bail early if already activated
if windows_is_activated():
print_info('This system is already activated')
sleep(5)
exit_script()
other_results = {
'Error': {
'BIOSKeyNotFoundError': 'BIOS key not found.',
}}
# Determine activation method
activation_methods = [
{'Name': 'Activate with BIOS key', 'Function': activate_with_bios},
]
if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
activation_methods[0]['Disabled'] = True
actions = [
{'Name': 'Quit', 'Letter': 'Q'},
]
# Determine activation method
activation_methods = [
{'Name': 'Activate with BIOS key', 'Function': activate_with_bios},
]
if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
activation_methods[0]['Disabled'] = True
actions = [
{'Name': 'Quit', 'Letter': 'Q'},
]
while True:
selection = menu_select(
'{}: Windows Activation Menu'.format(KIT_NAME_FULL),
main_entries=activation_methods, action_entries=actions)
while True:
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'],
function = activation_methods[int(selection)-1]['Function'],
other_results=other_results)
if result['CS']:
break
else:
sleep(2)
elif selection == 'Q':
exit_script()
# Done
print_success('\nDone.')
pause("Press Enter to exit...")
if (selection.isnumeric()):
result = try_and_print(
message = activation_methods[int(selection)-1]['Name'],
function = activation_methods[int(selection)-1]['Function'],
other_results=other_results)
if result['CS']:
break
else:
sleep(2)
elif selection == 'Q':
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_success('\nDone.')
pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,81 @@
#!/bin/env python3
#
## Convert saved WiFi connections for NetworkManager
import os
import re
import sys
import uuid
KNOWN_NETWORKS = '/root/known_networks'
TEMPLATE = '''[connection]
id={ssid}
uuid={uuid}
type=wifi
permissions=user:{user}:;
[wifi]
mac-address-blacklist=
mode=infrastructure
ssid={ssid}
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk={password}
[ipv4]
dns-search=
method=auto
[ipv6]
addr-gen-mode=stable-privacy
dns-search=
method=auto
'''
def get_user_name():
"""Get user name, returns str."""
user = None
# Get running user
if 'SUDO_USER' in os.environ:
user = os.environ.get('SUDO_USER')
else:
user = os.environ.get('USER')
# Check if user manually specified
for a in sys.argv:
a = a.strip().lower()
if a.startswith('--user='):
user = a.replace('--user=', '')
return user
if __name__ == '__main__':
known_networks = {}
#try:
with open('/root/known_networks', 'r') as f:
for line in f.readlines():
r = re.search(r"^'(.*)':\s+'(.*)'", line.strip())
if r:
known_networks[r.group(1)] = r.group(2)
for ssid, password in known_networks.items():
out_path = '{}/{}.nmconnection'.format(
'/etc/NetworkManager/system-connections',
ssid,
)
if not os.path.exists(out_path):
with open(out_path, 'w') as f:
f.write(TEMPLATE.format(
user=get_user_name(),
ssid=ssid,
password=password,
uuid=uuid.uuid4(),
))
os.chmod(out_path, 0o600)
#except:
# # Meh
# pass
# vim: sts=2 sw=2 ts=2

View file

@ -1,35 +0,0 @@
sensors.py
==========
python bindings using ctypes for libsensors3 of the [lm-sensors project](https://github.com/groeck/lm-sensors). The code was written against libsensors 3.3.4.
For documentation of the low level API see [sensors.h](https://github.com/groeck/lm-sensors/blob/master/lib/sensors.h). For an example of the high level API see [example.py](example.py).
For a GUI application that displays the sensor readings and is based on this library, take a look at [sensors-unity](https://launchpad.net/sensors-unity).
Features
--------
* Full access to low level libsensors3 API
* High level iterator API
* unicode handling
* Python2 and Python3 compatible
Licensing
---------
LGPLv2 (same as libsensors3)
Usage Notes
-----------
As Python does not support call by reference for primitive types some of the libsensors API had to be adapted:
```python
# nr is changed by refrence in the C API
chip_name, nr = sensors.get_detected_chips(None, nr)
# returns the value. throws on error
val = sensors.get_value(chip, subfeature_nr)
```
Missing Features (pull requests are welcome):
* `sensors_subfeature_type` enum
* `sensors_get_subfeature`
* Error handlers

View file

@ -1,236 +0,0 @@
"""
@package sensors.py
Python Bindings for libsensors3
use the documentation of libsensors for the low level API.
see example.py for high level API usage.
@author: Pavel Rojtberg (http://www.rojtberg.net)
@see: https://github.com/paroj/sensors.py
@copyright: LGPLv2 (same as libsensors) <http://opensource.org/licenses/LGPL-2.1>
"""
from ctypes import *
import ctypes.util
_libc = cdll.LoadLibrary(ctypes.util.find_library("c"))
# see https://github.com/paroj/sensors.py/issues/1
_libc.free.argtypes = [c_void_p]
_hdl = cdll.LoadLibrary(ctypes.util.find_library("sensors"))
version = c_char_p.in_dll(_hdl, "libsensors_version").value.decode("ascii")
class bus_id(Structure):
_fields_ = [("type", c_short),
("nr", c_short)]
class chip_name(Structure):
_fields_ = [("prefix", c_char_p),
("bus", bus_id),
("addr", c_int),
("path", c_char_p)]
class feature(Structure):
_fields_ = [("name", c_char_p),
("number", c_int),
("type", c_int)]
# sensors_feature_type
IN = 0x00
FAN = 0x01
TEMP = 0x02
POWER = 0x03
ENERGY = 0x04
CURR = 0x05
HUMIDITY = 0x06
MAX_MAIN = 0x7
VID = 0x10
INTRUSION = 0x11
MAX_OTHER = 0x12
BEEP_ENABLE = 0x18
class subfeature(Structure):
_fields_ = [("name", c_char_p),
("number", c_int),
("type", c_int),
("mapping", c_int),
("flags", c_uint)]
_hdl.sensors_get_detected_chips.restype = POINTER(chip_name)
_hdl.sensors_get_features.restype = POINTER(feature)
_hdl.sensors_get_all_subfeatures.restype = POINTER(subfeature)
_hdl.sensors_get_label.restype = c_void_p # return pointer instead of str so we can free it
_hdl.sensors_get_adapter_name.restype = c_char_p # docs do not say whether to free this or not
_hdl.sensors_strerror.restype = c_char_p
### RAW API ###
MODE_R = 1
MODE_W = 2
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)
def cleanup():
_hdl.sensors_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):
return _hdl.sensors_strerror(errnum).decode("utf-8")
def free_chip_name(chip):
_hdl.sensors_free_chip_name(byref(chip))
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
def chip_snprintf_name(chip, buffer_size=200):
"""
@param buffer_size defaults to the size used in the sensors utility
"""
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):
"""
@attention this function was not tested
"""
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")
def get_features(chip, nr):
"""
@return: (feature, next nr to query)
"""
_nr = c_int(nr)
feature = _hdl.sensors_get_features(byref(chip), byref(_nr))
feature = feature.contents if bool(feature) else None
return feature, _nr.value
def get_label(chip, feature):
ptr = _hdl.sensors_get_label(byref(chip), byref(feature))
val = cast(ptr, c_char_p).value.decode("utf-8")
_libc.free(ptr)
return val
def get_all_subfeatures(chip, feature, nr):
"""
@return: (subfeature, next nr to query)
"""
_nr = c_int(nr)
subfeature = _hdl.sensors_get_all_subfeatures(byref(chip), byref(feature), byref(_nr))
subfeature = subfeature.contents if bool(subfeature) else None
return subfeature, _nr.value
def get_value(chip, subfeature_nr):
val = c_double()
err = _hdl.sensors_get_value(byref(chip), subfeature_nr, byref(val))
if err < 0:
raise Exception(strerror(err))
return val.value
def set_value(chip, subfeature_nr, value):
"""
@attention this function was not tested
"""
val = c_double(value)
err = _hdl.sensors_set_value(byref(chip), subfeature_nr, byref(val))
if err < 0:
raise Exception(strerror(err))
### Convenience API ###
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__()

View file

@ -1,619 +1,149 @@
#!/usr/bin/env bash
#!/bin/env python3
#
## Wizard Kit: UFD Build Tool
#
# Based on a template by BASH3 Boilerplate v2.3.0
# http://bash3boilerplate.sh/#authors
#
# The MIT License (MIT)
# Copyright (c) 2013 Kevin van Zonneveld and contributors
# You are not obligated to bundle the LICENSE file with your b3bp projects as long
# as you leave these references intact in the header comments of your source files.
# Exit on error. Append "|| true" if you expect an error.
set -o errexit
# Exit on error inside any functions or subshells.
set -o errtrace
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
set -o nounset
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip`
set -o pipefail
# Turn on traces, useful while debugging but commented out by default
# set -o xtrace
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
__i_am_main_script="0" # false
if [[ "${__usage+x}" ]]; then
if [[ "${BASH_SOURCE[1]}" = "${0}" ]]; then
__i_am_main_script="1" # true
fi
__b3bp_external_usage="true"
__b3bp_tmp_source_idx=1
fi
else
__i_am_main_script="1" # true
[[ "${__usage+x}" ]] && unset -v __usage
[[ "${__helptext+x}" ]] && unset -v __helptext
fi
# Set magic variables for current file, directory, os, etc.
__dir="$(cd "$(dirname "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")"
__base="$(basename "${__file}" .sh)"
__wd="$(pwd)"
__usage_example="Usage: sudo $(basename "${0}") --ufd-device [device] --linux-iso [path] --main-kit [path] --winpe-iso [path]"
__all_args=""
for a in "${@}"; do
if [[ "${a:0:1}" == "-" ]]; then
__all_args="${__all_args} ${a}"
else
__all_args="${__all_args} \"${a}\""
fi
done
# Define the environment variables (and their defaults) that this script depends on
LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency
NO_COLOR="${NO_COLOR:-}" # true = disable color. otherwise autodetected
### Functions
##############################################################################
function __b3bp_log () {
local log_level="${1}"
shift
# shellcheck disable=SC2034
local color_debug="\x1b[35m"
# shellcheck disable=SC2034
local color_info="\x1b[32m"
# shellcheck disable=SC2034
local color_notice="\x1b[34m"
# shellcheck disable=SC2034
local color_warning="\x1b[33m"
# shellcheck disable=SC2034
local color_error="\x1b[31m"
# shellcheck disable=SC2034
local color_critical="\x1b[1;31m"
# shellcheck disable=SC2034
local color_alert="\x1b[1;33;41m"
# shellcheck disable=SC2034
local color_emergency="\x1b[1;4;5;33;41m"
local colorvar="color_${log_level}"
local color="${!colorvar:-${color_error}}"
local color_reset="\x1b[0m"
if [[ "${NO_COLOR:-}" = "true" ]] || ( [[ "${TERM:-}" != *"256color"* ]] && [[ "${TERM:-}" != "xterm"* ]] && [[ "${TERM:-}" != "screen"* ]] ) || [[ ! -t 2 ]]; then
if [[ "${NO_COLOR:-}" != "false" ]]; then
# Don't use colors on pipes or non-recognized terminals
color=""; color_reset=""
fi
fi
# all remaining arguments are to be printed
local log_line=""
while IFS=$'\n' read -r log_line; do
echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%9s]" "${log_level}")${color_reset} ${log_line}" 1>&2
done <<< "${@:-}"
}
function emergency () { __b3bp_log emergency "${@}"; exit 1; }
function alert () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && __b3bp_log alert "${@}"; true; }
function critical () { [[ "${LOG_LEVEL:-0}" -ge 2 ]] && __b3bp_log critical "${@}"; true; }
function error () { [[ "${LOG_LEVEL:-0}" -ge 3 ]] && __b3bp_log error "${@}"; true; }
function warning () { [[ "${LOG_LEVEL:-0}" -ge 4 ]] && __b3bp_log warning "${@}"; true; }
function notice () { [[ "${LOG_LEVEL:-0}" -ge 5 ]] && __b3bp_log notice "${@}"; true; }
function info () { [[ "${LOG_LEVEL:-0}" -ge 6 ]] && __b3bp_log info "${@}"; true; }
function debug () { [[ "${LOG_LEVEL:-0}" -ge 7 ]] && __b3bp_log debug "${@}"; true; }
function help () {
echo "" 1>&2
echo " ${*}" 1>&2
echo "" 1>&2
echo " ${__usage:-No usage available}" 1>&2
echo "" 1>&2
if [[ "${__helptext:-}" ]]; then
echo " ${__helptext}" 1>&2
echo "" 1>&2
fi
exit 1
}
### Parse commandline options
##############################################################################
# Commandline options. This defines the usage page, and is used to parse cli
# opts & defaults from. The parsing is unforgiving so be precise in your syntax
# - A short option must be preset for every long option; but every short option
# need not have a long option
# - `--` is respected as the separator between options and arguments
# - We do not bash-expand defaults, so setting '~/app' as a default will not resolve to ${HOME}.
# you can use bash variables to work around this (so use ${HOME} instead)
# shellcheck disable=SC2015
[[ "${__usage+x}" ]] || read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered
OPTIONS:
-u --ufd-device [arg] Device to which the kit will be applied
-m --main-kit [arg] Path to the Main Kit
-l --linux-iso [arg] Path to the Linux ISO
-w --winpe-iso [arg] Path to the WinPE ISO
-e --extra-dir [arg] Path to the Extra folder (optional)
-h --help This page
ADVANCED:
-d --debug Enable debug mode
-v --verbose Enable verbose mode
-M --use-mbr Use real MBR instead of GPT w/ Protective MBR
-F --force Bypass all confirmation messages. USE WITH EXTREME CAUTION!
EOF
# shellcheck disable=SC2015
[[ "${__helptext+x}" ]] || read -r -d '' __helptext <<-'EOF' || true # exits non-zero when EOF encountered
Paths can be relative to the current working directory or absolute
EOF
# Translate usage string -> getopts arguments, and set $arg_<flag> defaults
while read -r __b3bp_tmp_line; do
if [[ "${__b3bp_tmp_line}" =~ ^- ]]; then
# fetch single character version of option string
__b3bp_tmp_opt="${__b3bp_tmp_line%% *}"
__b3bp_tmp_opt="${__b3bp_tmp_opt:1}"
# fetch long version if present
__b3bp_tmp_long_opt=""
if [[ "${__b3bp_tmp_line}" = *"--"* ]]; then
__b3bp_tmp_long_opt="${__b3bp_tmp_line#*--}"
__b3bp_tmp_long_opt="${__b3bp_tmp_long_opt%% *}"
fi
# map opt long name to+from opt short name
printf -v "__b3bp_tmp_opt_long2short_${__b3bp_tmp_long_opt//-/_}" '%s' "${__b3bp_tmp_opt}"
printf -v "__b3bp_tmp_opt_short2long_${__b3bp_tmp_opt}" '%s' "${__b3bp_tmp_long_opt//-/_}"
# check if option takes an argument
if [[ "${__b3bp_tmp_line}" =~ \[.*\] ]]; then
__b3bp_tmp_opt="${__b3bp_tmp_opt}:" # add : if opt has arg
__b3bp_tmp_init="" # it has an arg. init with ""
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "1"
elif [[ "${__b3bp_tmp_line}" =~ \{.*\} ]]; then
__b3bp_tmp_opt="${__b3bp_tmp_opt}:" # add : if opt has arg
__b3bp_tmp_init="" # it has an arg. init with ""
# remember that this option requires an argument
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "2"
else
__b3bp_tmp_init="0" # it's a flag. init with 0
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "0"
fi
__b3bp_tmp_opts="${__b3bp_tmp_opts:-}${__b3bp_tmp_opt}"
fi
[[ "${__b3bp_tmp_opt:-}" ]] || continue
if [[ "${__b3bp_tmp_line}" =~ (^|\.\ *)Default= ]]; then
# ignore default value if option does not have an argument
__b3bp_tmp_varname="__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}"
if [[ "${!__b3bp_tmp_varname}" != "0" ]]; then
__b3bp_tmp_init="${__b3bp_tmp_line##*Default=}"
__b3bp_tmp_re='^"(.*)"$'
if [[ "${__b3bp_tmp_init}" =~ ${__b3bp_tmp_re} ]]; then
__b3bp_tmp_init="${BASH_REMATCH[1]}"
else
__b3bp_tmp_re="^'(.*)'$"
if [[ "${__b3bp_tmp_init}" =~ ${__b3bp_tmp_re} ]]; then
__b3bp_tmp_init="${BASH_REMATCH[1]}"
fi
fi
fi
fi
if [[ "${__b3bp_tmp_line}" =~ (^|\.\ *)Required\. ]]; then
# remember that this option requires an argument
printf -v "__b3bp_tmp_has_arg_${__b3bp_tmp_opt:0:1}" '%s' "2"
fi
printf -v "arg_${__b3bp_tmp_opt:0:1}" '%s' "${__b3bp_tmp_init}"
done <<< "${__usage:-}"
# run getopts only if options were specified in __usage
if [[ "${__b3bp_tmp_opts:-}" ]]; then
# Allow long options like --this
__b3bp_tmp_opts="${__b3bp_tmp_opts}-:"
# Reset in case getopts has been used previously in the shell.
OPTIND=1
# start parsing command line
set +o nounset # unexpected arguments will cause unbound variables
# to be dereferenced
# Overwrite $arg_<flag> defaults with the actual CLI options
while getopts "${__b3bp_tmp_opts}" __b3bp_tmp_opt; do
[[ "${__b3bp_tmp_opt}" = "?" ]] && help "Invalid use of script: ${*} "
if [[ "${__b3bp_tmp_opt}" = "-" ]]; then
# OPTARG is long-option-name or long-option=value
if [[ "${OPTARG}" =~ .*=.* ]]; then
# --key=value format
__b3bp_tmp_long_opt=${OPTARG/=*/}
# Set opt to the short option corresponding to the long option
__b3bp_tmp_varname="__b3bp_tmp_opt_long2short_${__b3bp_tmp_long_opt//-/_}"
printf -v "__b3bp_tmp_opt" '%s' "${!__b3bp_tmp_varname}"
OPTARG=${OPTARG#*=}
else
# --key value format
# Map long name to short version of option
__b3bp_tmp_varname="__b3bp_tmp_opt_long2short_${OPTARG//-/_}"
printf -v "__b3bp_tmp_opt" '%s' "${!__b3bp_tmp_varname}"
# Only assign OPTARG if option takes an argument
__b3bp_tmp_varname="__b3bp_tmp_has_arg_${__b3bp_tmp_opt}"
printf -v "OPTARG" '%s' "${@:OPTIND:${!__b3bp_tmp_varname}}"
# shift over the argument if argument is expected
((OPTIND+=__b3bp_tmp_has_arg_${__b3bp_tmp_opt}))
fi
# we have set opt/OPTARG to the short value and the argument as OPTARG if it exists
fi
__b3bp_tmp_varname="arg_${__b3bp_tmp_opt:0:1}"
__b3bp_tmp_default="${!__b3bp_tmp_varname}"
__b3bp_tmp_value="${OPTARG}"
if [[ -z "${OPTARG}" ]] && [[ "${__b3bp_tmp_default}" = "0" ]]; then
__b3bp_tmp_value="1"
fi
printf -v "${__b3bp_tmp_varname}" '%s' "${__b3bp_tmp_value}"
debug "cli arg ${__b3bp_tmp_varname} = (${__b3bp_tmp_default}) -> ${!__b3bp_tmp_varname}"
done
set -o nounset # no more unbound variable references expected
shift $((OPTIND-1))
if [[ "${1:-}" = "--" ]] ; then
shift
fi
fi
### Automatic validation of required option arguments
##############################################################################
for __b3bp_tmp_varname in ${!__b3bp_tmp_has_arg_*}; do
# validate only options which required an argument
[[ "${!__b3bp_tmp_varname}" = "2" ]] || continue
__b3bp_tmp_opt_short="${__b3bp_tmp_varname##*_}"
__b3bp_tmp_varname="arg_${__b3bp_tmp_opt_short}"
[[ "${!__b3bp_tmp_varname}" ]] && continue
__b3bp_tmp_varname="__b3bp_tmp_opt_short2long_${__b3bp_tmp_opt_short}"
printf -v "__b3bp_tmp_opt_long" '%s' "${!__b3bp_tmp_varname}"
[[ "${__b3bp_tmp_opt_long:-}" ]] && __b3bp_tmp_opt_long=" (--${__b3bp_tmp_opt_long//_/-})"
help "Option -${__b3bp_tmp_opt_short}${__b3bp_tmp_opt_long:-} requires an argument"
done
### Cleanup Environment variables
##############################################################################
for __tmp_varname in ${!__b3bp_tmp_*}; do
unset -v "${__tmp_varname}"
done
unset -v __tmp_varname
### Externally supplied __usage. Nothing else to do here
##############################################################################
if [[ "${__b3bp_external_usage:-}" = "true" ]]; then
unset -v __b3bp_external_usage
return
fi
### Signal trapping and backtracing
##############################################################################
function __b3bp_cleanup_before_exit () {
if [[ "$EUID" -eq 0 ]]; then
for d in Dest Linux WinPE; do
if [[ -d "/mnt/${d}" ]]; then
umount "/mnt/${d}" || true
rmdir "/mnt/${d}" || true
fi
done
fi
if [[ "${?}" != "0" ]]; then
info "Sources unmounted"
fi
if [[ ${arg_F:-} == 0 && "${SILENT:-False}" == "False" ]]; then
read -r -p "Press Enter to exit... " ignored_var 2>&1
fi
}
trap __b3bp_cleanup_before_exit EXIT
# requires `set -o errtrace`
__b3bp_err_report() {
local error_code
error_code=${?}
error "Error in ${__file} in function ${1} on line ${2}"
exit ${error_code}
}
# Uncomment the following line for always providing an error backtrace
trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR
### Command-line argument switches (like -d for debugmode, -h for showing helppage)
##############################################################################
# debug mode
if [[ "${arg_d:?}" = "1" ]]; then
set -o xtrace
LOG_LEVEL="7"
# Enable error backtracing
trap '__b3bp_err_report "${FUNCNAME:-.}" ${LINENO}' ERR
fi
# verbose mode
if [[ "${arg_v:?}" = "1" ]]; then
set -o verbose
fi
### Validation. Error out if the things required for your script are not present
##############################################################################
if [[ "${arg_F:?}" == 1 ]]; then
SILENT="True"
else
SILENT="False"
fi
if [[ "${arg_M:?}" == 1 ]]; then
USE_MBR="True"
else
USE_MBR="False"
fi
if [[ "${arg_h:?}" == 1 ]]; then
help "${__usage_example}"
else
# Print warning line
[[ "${arg_u:-}" ]] || echo " -u or --ufd-device is required"
[[ "${arg_m:-}" ]] || echo " -m or --main-kit is required"
[[ "${arg_l:-}" ]] || echo " -l or --linux-iso is required"
[[ "${arg_w:-}" ]] || echo " -w or --winpe-iso is required"
# Bail if necessary
[[ "${arg_u:-}" ]] || help "${__usage_example}"
[[ "${arg_l:-}" ]] || help "${__usage_example}"
[[ "${arg_m:-}" ]] || help "${__usage_example}"
[[ "${arg_w:-}" ]] || help "${__usage_example}"
fi
[[ "${LOG_LEVEL:-}" ]] || emergency "Cannot continue without LOG_LEVEL. "
### More functions
##############################################################################
function abort () {
local abort_message="Aborted"
[[ "${1:-}" ]] && abort_message="${1}" || true
error "${abort_message}"
#echo -e "${YELLOW}${abort_message}${CLEAR}"
exit 1
}
function ask() {
if [[ "${SILENT}" == "True" ]]; then
echo -e "${1:-} Yes ${BLUE}(Silent)${CLEAR}"
return 0
fi
while :; do
read -p "${1:-} [Y/N] " -r answer
if echo "$answer" | egrep -iq '^(y|yes|sure)$'; then
return 0
elif echo "$answer" | egrep -iq '^(n|no|nope)$'; then
return 1
fi
done
}
### Runtime
##############################################################################
# VARIABLES
DEST_DEV="${arg_u}"
DEST_PAR="${DEST_DEV}1"
LOG_FILE="$(getent passwd "$SUDO_USER" | cut -d: -f6)/Logs/build-ufd_${DEST_DEV##*/}_$(date +%Y-%m-%d_%H%M_%z).log"
MAIN_PY="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/settings/main.py"
RSYNC_ARGS="-hrtuvS --modify-window=1 --progress"
MAIN_KIT="$(realpath "${arg_m:-}" 2>/dev/null || true)"
LINUX_ISO="$(realpath "${arg_l:-}" 2>/dev/null || true)"
WINPE_ISO="$(realpath "${arg_w:-}" 2>/dev/null || true)"
EXTRA_DIR="$(realpath "${arg_e:-}" 2>/dev/null || true)"
mkdir -p "$(dirname "$LOG_FILE")"
chown "$SUDO_USER:$SUDO_USER" -R "$(dirname "$LOG_FILE")"
# COLORS
CLEAR="\e[0m"
RED="\e[31m"
GREEN="\e[32m"
YELLOW="\e[33m"
BLUE="\e[34m"
# Load main.py settings
if [ ! -f "${MAIN_PY}" ]; then
echo -e "${RED}ERROR${CLEAR}: ${MAIN_PY} not found."
abort
fi
while read line; do
if echo "${line}" | egrep -q "^\w+='"; then
line="$(echo "${line}" | sed -r 's/[\r\n]+//')"
eval "${line}"
fi
done < "${MAIN_PY}"
if [ -z ${KIT_NAME_FULL+x} ]; then
# KIT_NAME_FULL is not set, assume main.py missing or malformatted
echo -e "${RED}ERROR${CLEAR}: failed to load settings from ${MAIN_PY}"
abort
fi
ISO_LABEL="${KIT_NAME_SHORT}_LINUX"
UFD_LABEL="${KIT_NAME_SHORT}_UFD"
# Check if root
if [[ "$EUID" -ne 0 ]]; then
echo -e "${RED}ERROR${CLEAR}: This script must be run as root."
abort
fi
# Check if in tmux
if ! tmux list-session 2>/dev/null | grep -q "build-ufd"; then
# Reload in tmux
eval tmux new-session -s "build-ufd" "${0:-}" ${__all_args}
SILENT="True" # avoid two "Press Enter to exit..." prompts
exit 0
fi
# Header
echo -e "${GREEN}${KIT_NAME_FULL}${CLEAR}: UFD Build Tool"
echo ""
# Verify sources
[[ -b "${DEST_DEV}" ]] || abort "${DEST_DEV} is not a valid device."
[[ -d "${MAIN_KIT}/.bin" ]] || abort "Invalid Main Kit, ${MAIN_KIT}/.bin not found."
[[ -e "${LINUX_ISO}" ]] || abort "Linux ISO not found."
[[ -e "${WINPE_ISO}" ]] || abort "WinPE ISO not found."
if [[ ! -z "${arg_e:-}" ]]; then
[[ -d "${EXTRA_DIR}" ]] || abort "Extra Dir not found."
fi
# Print Info
echo -e "${BLUE}Sources${CLEAR}"
echo "Main Kit: ${MAIN_KIT}"
echo "Linux ISO: ${LINUX_ISO}"
echo "WinPE ISO: ${WINPE_ISO}"
echo "Extra Dir: ${EXTRA_DIR:-(Not Specified)}"
echo ""
echo -e "${BLUE}Destination${CLEAR}"
lsblk -n -o NAME,LABEL,SIZE,MODEL,SERIAL "${DEST_DEV}"
if [[ "${USE_MBR}" == "True" ]]; then
echo -e "${YELLOW}Formatting using legacy MBR${CLEAR}"
fi
echo ""
# Ask before starting job
echo ""
if ask "Is the above information correct?"; then
echo ""
echo -e "${YELLOW}SAFETY CHECK${CLEAR}"
echo "All data will be DELETED from the disk and partition(s) listed above."
echo -e "This is irreversible and will lead to ${RED}DATA LOSS.${CLEAR}"
if ! ask "Asking again to confirm, is this correct?"; then
abort
fi
else
abort
fi
# Start Build
echo ""
echo -e "${GREEN}Building Kit${CLEAR}"
touch "${LOG_FILE}"
tmux split-window -dl 10 tail -f "${LOG_FILE}"
# Format
echo "Formatting drive..."
if [[ "${USE_MBR}" == "True" ]]; then
parted "${DEST_DEV}" --script -- mklabel msdos mkpart primary fat32 4MiB -1s >> "${LOG_FILE}" 2>&1
parted "${DEST_DEV}" set 1 boot on >> "${LOG_FILE}" 2>&1
else
parted "${DEST_DEV}" --script -- mklabel gpt mkpart primary fat32 4MiB -4MiB >> "${LOG_FILE}" 2>&1
parted "${DEST_DEV}" set 1 legacy_boot on >> "${LOG_FILE}" 2>&1
#parted "${DEST_DEV}" disk_set pmbr_boot on >> "${LOG_FILE}" 2>&1
# pmbr_boot breaks detection on some UEFI MOBOs
fi
mkfs.vfat -F 32 -n "${UFD_LABEL}" "${DEST_PAR}" >> "${LOG_FILE}" 2>&1
# Mount sources and dest
echo "Mounting sources and destination..."
mkdir /mnt/{Dest,Linux,WinPE} -p >> "${LOG_FILE}" 2>&1
mount ${DEST_PAR} /mnt/Dest >> "${LOG_FILE}" 2>&1
mount "${LINUX_ISO}" /mnt/Linux -r >> "${LOG_FILE}" 2>&1
mount "${WINPE_ISO}" /mnt/WinPE -r >> "${LOG_FILE}" 2>&1
# Copy files
echo "Copying Linux files..."
rsync ${RSYNC_ARGS} /mnt/Linux/* /mnt/Dest/ >> "${LOG_FILE}" 2>&1
sed -i "s/${ISO_LABEL}/${UFD_LABEL}/" /mnt/Dest/EFI/boot/refind.conf
sed -i "s/#UFD#//" /mnt/Dest/EFI/boot/refind.conf
sed -i "s/${ISO_LABEL}/${UFD_LABEL}/" /mnt/Dest/arch/boot/syslinux/*cfg
sed -i "s/#UFD#//" /mnt/Dest/arch/boot/syslinux/*cfg
echo "Copying WinPE files..."
rsync ${RSYNC_ARGS} /mnt/WinPE/{Boot,bootmgr{,.efi},en-us,sources} /mnt/Dest/ >> "${LOG_FILE}" 2>&1
rsync ${RSYNC_ARGS} /mnt/WinPE/EFI/Microsoft /mnt/Dest/EFI/ >> "${LOG_FILE}" 2>&1
rsync ${RSYNC_ARGS} /mnt/WinPE/EFI/Boot/* /mnt/Dest/EFI/Microsoft/ >> "${LOG_FILE}" 2>&1
rsync ${RSYNC_ARGS} /mnt/WinPE/{Boot/{BCD,boot.sdi},bootmgr} /mnt/Dest/sources/ >> "${LOG_FILE}" 2>&1
echo "Copying Main Kit..."
rsync ${RSYNC_ARGS} "${MAIN_KIT}/" "/mnt/Dest/${KIT_NAME_FULL}/" >> "${LOG_FILE}" 2>&1
if [[ ! -z "${EXTRA_DIR:-}" ]]; then
echo "Copying Extra files..."
rsync ${RSYNC_ARGS} "${EXTRA_DIR}"/ /mnt/Dest/ >> "${LOG_FILE}" 2>&1
fi
# Install syslinux
echo "Copying Syslinux files..."
rsync ${RSYNC_ARGS} /usr/lib/syslinux/bios/*.c32 /mnt/Dest/arch/boot/syslinux/ >> "${LOG_FILE}" 2>&1
syslinux --install -d /arch/boot/syslinux/ ${DEST_PAR} >> "${LOG_FILE}" 2>&1
echo "Unmounting destination..."
umount /mnt/Dest >> "${LOG_FILE}" 2>&1
rmdir /mnt/Dest >> "${LOG_FILE}" 2>&1
sync
echo "Installing Syslinux MBR..."
if [[ "${USE_MBR}" == "True" ]]; then
dd bs=440 count=1 if=/usr/lib/syslinux/bios/mbr.bin of=${DEST_DEV} >> "${LOG_FILE}" 2>&1
else
dd bs=440 count=1 if=/usr/lib/syslinux/bios/gptmbr.bin of=${DEST_DEV} >> "${LOG_FILE}" 2>&1
fi
sync
# Cleanup
echo "Hiding boot files..."
echo "drive s: file=\"${DEST_PAR}\"" > /root/.mtoolsrc
echo 'mtools_skip_check=1' >> /root/.mtoolsrc
for item in arch Boot bootmgr{,.efi} EFI en-us images isolinux sources "${KIT_NAME_FULL}"/{.bin,.cbin}; do
yes | mattrib +h "S:/${item}" >> "${LOG_FILE}" 2>&1 || true
done
sync
# Unmount Sources
echo "Unmounting sources..."
for d in Linux WinPE; do
umount "/mnt/${d}" >> "${LOG_FILE}" 2>&1 || true
rmdir "/mnt/${d}" >> "${LOG_FILE}" 2>&1 || true
done
# Close progress pane
pkill -f "tail.*${LOG_FILE}"
# Done
echo ""
echo "Done."
echo ""
exit 0
# pylint: disable=no-name-in-module,wildcard-import,wrong-import-position
# vim: sts=2 sw=2 ts=2
"""Wizard Kit: UFD build tool"""
import os
import sys
# Init
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from docopt import docopt
from functions.common import *
from functions.ufd import *
from settings.ufd import *
init_global_vars(silent=True)
# Main section
if __name__ == '__main__':
# pylint: disable=invalid-name
# Set log
try:
global_vars['LogDir'] = '{}/Logs'.format(
get_user_home(get_user_name()))
set_log_file('Build UFD ({Date-Time}).log'.format(**global_vars))
except: # pylint: disable=bare-except
major_exception()
# Header
print_success(KIT_NAME_FULL)
print_standard('UFD Build Tool')
print_standard(' ')
# Check if running as root
if not running_as_root():
print_error('ERROR: This script is meant to be run as root.')
abort(False)
# Docopt
try:
args = docopt(DOCSTRING)
except SystemExit as sys_exit:
# Catch docopt exits
exit_script(sys_exit.code)
except: # pylint: disable=bare-except
major_exception()
try:
# Verify selections
ufd_dev = verify_ufd(args['--ufd-device'])
sources = verify_sources(args, UFD_SOURCES)
show_selections(args, sources, ufd_dev, UFD_SOURCES)
if not args['--force']:
confirm_selections(args)
# Prep UFD
if not args['--update']:
print_info('Prep UFD')
prep_device(ufd_dev, UFD_LABEL, use_mbr=args['--use-mbr'])
# Mount UFD
try_and_print(
indent=2,
message='Mounting UFD...',
function=mount,
mount_source=find_first_partition(ufd_dev),
mount_point='/mnt/UFD',
read_write=True,
)
# Remove Arch folder
if args['--update']:
try_and_print(
indent=2,
message='Removing Linux...',
function=remove_arch,
)
# Copy sources
print_standard(' ')
print_info('Copy Sources')
for s_label, s_path in sources.items():
try_and_print(
indent=2,
message='Copying {}...'.format(s_label),
function=copy_source,
source=s_path,
items=ITEMS[s_label],
overwrite=True,
)
# Update boot entries
print_standard(' ')
print_info('Boot Setup')
try_and_print(
indent=2,
message='Updating boot entries...',
function=update_boot_entries,
boot_entries=BOOT_ENTRIES,
boot_files=BOOT_FILES,
iso_label=ISO_LABEL,
ufd_label=UFD_LABEL,
)
# Install syslinux (to partition)
try_and_print(
indent=2,
message='Syslinux (partition)...',
function=install_syslinux_to_partition,
partition=find_first_partition(ufd_dev),
)
# Unmount UFD
try_and_print(
indent=2,
message='Unmounting UFD...',
function=unmount,
mount_point='/mnt/UFD',
)
# Install syslinux (to device)
try_and_print(
indent=2,
message='Syslinux (device)...',
function=install_syslinux_to_dev,
ufd_dev=ufd_dev,
use_mbr=args['--use-mbr'],
)
# Hide items
print_standard(' ')
print_info('Final Touches')
try_and_print(
indent=2,
message='Hiding items...',
function=hide_items,
ufd_dev=ufd_dev,
items=ITEMS_HIDDEN,
)
# Done
if not args['--force']:
print_standard('\nDone.')
pause('Press Enter to exit...')
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except: # pylint: disable=bare-except
major_exception()

View file

@ -79,21 +79,21 @@ if ($MyInvocation.InvocationName -ne ".") {
$Path = $Temp
# 7-Zip
DownloadFile -Path $Path -Name "7z-installer.msi" -Url "https://www.7-zip.org/a/7z1805.msi"
DownloadFile -Path $Path -Name "7z-extra.7z" -Url "https://www.7-zip.org/a/7z1805-extra.7z"
DownloadFile -Path $Path -Name "7z-installer.msi" -Url "https://www.7-zip.org/a/7z1900.msi"
DownloadFile -Path $Path -Name "7z-extra.7z" -Url "https://www.7-zip.org/a/7z1900-extra.7z"
# ConEmu
$Url = "https://github.com/Maximus5/ConEmu/releases/download/v18.06.26/ConEmuPack.180626.7z"
$Url = "https://github.com/Maximus5/ConEmu/releases/download/v19.03.10/ConEmuPack.190310.7z"
DownloadFile -Path $Path -Name "ConEmuPack.7z" -Url $Url
# Notepad++
$Url = "https://notepad-plus-plus.org/repository/7.x/7.5.8/npp.7.5.8.bin.minimalist.7z"
$Url = "https://notepad-plus-plus.org/repository/7.x/7.6.4/npp.7.6.4.bin.minimalist.7z"
DownloadFile -Path $Path -Name "npp.7z" -Url $Url
# Python
$Url = "https://www.python.org/ftp/python/3.7.0/python-3.7.0-embed-win32.zip"
$Url = "https://www.python.org/ftp/python/3.7.2/python-3.7.2.post1-embed-win32.zip"
DownloadFile -Path $Path -Name "python32.zip" -Url $Url
$Url = "https://www.python.org/ftp/python/3.7.0/python-3.7.0-embed-amd64.zip"
$Url = "https://www.python.org/ftp/python/3.7.2/python-3.7.2.post1-embed-amd64.zip"
DownloadFile -Path $Path -Name "python64.zip" -Url $Url
# Python: psutil

View file

@ -131,25 +131,25 @@ if ($MyInvocation.InvocationName -ne ".") {
## Download Tools ##
$ToolSources = @(
# 7-Zip
@("7z-installer.msi", "https://www.7-zip.org/a/7z1805.msi"),
@("7z-extra.7z", "https://www.7-zip.org/a/7z1805-extra.7z"),
@("7z-installer.msi", "https://www.7-zip.org/a/7z1900.msi"),
@("7z-extra.7z", "https://www.7-zip.org/a/7z1900-extra.7z"),
# Blue Screen View
@("bluescreenview32.zip", "http://www.nirsoft.net/utils/bluescreenview.zip"),
@("bluescreenview64.zip", "http://www.nirsoft.net/utils/bluescreenview-x64.zip"),
# ConEmu
@("ConEmuPack.7z", "https://github.com/Maximus5/ConEmu/releases/download/v18.06.26/ConEmuPack.180626.7z"),
@("ConEmuPack.7z", "https://github.com/Maximus5/ConEmu/releases/download/v19.03.10/ConEmuPack.190310.7z"),
# Fast Copy
@("fastcopy.zip", "http://ftp.vector.co.jp/70/64/2323/FastCopy354_installer.zip"),
@("fastcopy.zip", "http://ftp.vector.co.jp/71/31/2323/FastCopy363_installer.exe"),
# HWiNFO
@("hwinfo.zip", "http://app.oldfoss.com:81/download/HWiNFO/hwi_588.zip"),
@("hwinfo.zip", "http://files2.majorgeeks.com/377527622c5325acc1cb937fb149d0de922320c0/systeminfo/hwi_602.zip"),
# Killer Network Drivers
@(
"killerinf.zip",
("http://www.killernetworking.com"+(FindDynamicUrl "http://www.killernetworking.com/driver-downloads/item/killer-drivers-inf" "Download Killer-Ethernet").replace('&amp;', '&'))
("https://www.killernetworking.com"+(FindDynamicUrl "https://www.killernetworking.com/killersupport/category/other-downloads" "Download Killer-Ethernet").replace('&amp;', '&'))
),
# Notepad++
@("npp_x86.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.8/npp.7.5.8.bin.minimalist.7z"),
@("npp_amd64.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.8/npp.7.5.8.bin.minimalist.x64.7z"),
@("npp_x86.7z", "https://notepad-plus-plus.org/repository/7.x/7.6.4/npp.7.6.4.bin.minimalist.7z"),
@("npp_amd64.7z", "https://notepad-plus-plus.org/repository/7.x/7.6.4/npp.7.6.4.bin.minimalist.x64.7z"),
# NT Password Editor
@("ntpwed.zip", "http://cdslow.org.ru/files/ntpwedit/ntpwed07.zip"),
# Prime95
@ -159,8 +159,8 @@ if ($MyInvocation.InvocationName -ne ".") {
@("produkey32.zip", "http://www.nirsoft.net/utils/produkey.zip"),
@("produkey64.zip", "http://www.nirsoft.net/utils/produkey-x64.zip"),
# Python
@("python32.zip", "https://www.python.org/ftp/python/3.7.0/python-3.7.0-embed-win32.zip"),
@("python64.zip", "https://www.python.org/ftp/python/3.7.0/python-3.7.0-embed-amd64.zip"),
@("python32.zip", "https://www.python.org/ftp/python/3.7.2/python-3.7.2.post1-embed-win32.zip"),
@("python64.zip", "https://www.python.org/ftp/python/3.7.2/python-3.7.2.post1-embed-amd64.zip"),
# Python: psutil
@(
"psutil64.whl",
@ -182,8 +182,8 @@ if ($MyInvocation.InvocationName -ne ".") {
@("vcredist_x86.exe", "https://aka.ms/vs/15/release/vc_redist.x86.exe"),
@("vcredist_x64.exe", "https://aka.ms/vs/15/release/vc_redist.x64.exe"),
# wimlib-imagex
@("wimlib32.zip", "https://wimlib.net/downloads/wimlib-1.12.0-windows-i686-bin.zip"),
@("wimlib64.zip", "https://wimlib.net/downloads/wimlib-1.12.0-windows-x86_64-bin.zip")
@("wimlib32.zip", "https://wimlib.net/downloads/wimlib-1.13.0-windows-i686-bin.zip"),
@("wimlib64.zip", "https://wimlib.net/downloads/wimlib-1.13.0-windows-x86_64-bin.zip")
)
foreach ($Tool in $ToolSources) {
DownloadFile -Path $Temp -Name $Tool[0] -Url $Tool[1]

View file

@ -4,8 +4,7 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.cleanup import *
from functions.data import *
init_global_vars()
@ -13,30 +12,32 @@ os.system('title {}: CBS Cleanup'.format(KIT_NAME_FULL))
set_log_file('CBS Cleanup.log')
if __name__ == '__main__':
try:
# Prep
stay_awake()
clear_screen()
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?')
try:
# Prep
stay_awake()
clear_screen()
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()
# 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)
# 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...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,53 +4,54 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.repairs import *
init_global_vars()
os.system('title {}: Check Disk Tool'.format(KIT_NAME_FULL))
set_log_file('Check Disk.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
options = [
{'Name': 'Run CHKDSK scan (read-only)', 'Repair': False},
{'Name': 'Schedule CHKDSK scan (offline repair)', 'Repair': True}]
actions = [{'Name': 'Quit', 'Letter': 'Q'}]
selection = menu_select(
'{}: Check Disk Menu\n'.format(KIT_NAME_FULL),
main_entries=options,
action_entries=actions)
print_info('{}: Check Disk Menu\n'.format(KIT_NAME_FULL))
if selection == 'Q':
abort()
elif selection.isnumeric():
repair = options[int(selection)-1]['Repair']
if repair:
cs = 'Scheduled'
else:
cs = 'CS'
message = 'CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env'])
try_and_print(message=message, function=run_chkdsk,
cs=cs, other_results=other_results, repair=repair)
else:
abort()
try:
stay_awake()
clear_screen()
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
options = [
{'Name': 'Run CHKDSK scan (read-only)', 'Repair': False},
{'Name': 'Schedule CHKDSK scan (offline repair)', 'Repair': True}]
actions = [{'Name': 'Quit', 'Letter': 'Q'}]
selection = menu_select(
'{}: Check Disk Menu\n'.format(KIT_NAME_FULL),
main_entries=options,
action_entries=actions)
print_info('{}: Check Disk Menu\n'.format(KIT_NAME_FULL))
if selection == 'Q':
abort()
elif selection.isnumeric():
repair = options[int(selection)-1]['Repair']
if repair:
cs = 'Scheduled'
else:
cs = 'No issues'
message = 'CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env'])
try_and_print(message=message, function=run_chkdsk,
cs=cs, other_results=other_results, repair=repair)
else:
abort()
# Done
print_success('Done.')
pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_success('Done.')
pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -1,30 +0,0 @@
#!/bin/python3
#
## Wizard Kit: Network connection tool
import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.network import *
init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
# Connect
connect_to_network()
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()

View file

@ -2,42 +2,10 @@
#
## Wizard Kit: ddrescue TUI Launcher
source launch-in-tmux
SESSION_NAME="ddrescue-tui"
WINDOW_NAME="GNU ddrescue TUI"
MENU="ddrescue-tui-menu"
function ask() {
while :; do
read -p "$1 " -r answer
if echo "$answer" | egrep -iq '^(y|yes|sure)$'; then
return 0
elif echo "$answer" | egrep -iq '^(n|no|nope)$'; then
return 1
fi
done
}
die () {
echo "$0:" "$@" >&2
exit 1
}
# Check for running session
if tmux list-session | grep -q "$SESSION_NAME"; then
echo "WARNING: tmux session $SESSION_NAME already exists."
echo ""
if ask "Kill current session?"; then
tmux kill-session -t "$SESSION_NAME" || \
die "Failed to kill session: $SESSION_NAME"
else
echo "Aborted."
echo ""
echo -n "Press Enter to exit... "
read -r
exit 0
fi
fi
# Start session
tmux new-session -s "$SESSION_NAME" -n "$WINDOW_NAME" "$MENU" $*
WINDOW_NAME="ddrescue TUI"
TMUX_CMD="ddrescue-tui-menu"
launch_in_tmux "$@"

View file

@ -7,57 +7,58 @@ import sys
# Init
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.ddrescue import *
from functions.hw_diags import *
init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
args = list(sys.argv)
run_mode = ''
source_path = None
dest_path = None
# Parse args
try:
# Prep
clear_screen()
args = list(sys.argv)
run_mode = ''
source_path = None
dest_path = None
script_name = os.path.basename(args.pop(0))
run_mode = str(args.pop(0)).lower()
source_path = args.pop(0)
dest_path = args.pop(0)
except IndexError:
# We'll set the missing paths later
pass
# Parse args
try:
script_name = os.path.basename(args.pop(0))
run_mode = str(args.pop(0)).lower()
source_path = args.pop(0)
dest_path = args.pop(0)
except IndexError:
# We'll set the missing paths later
pass
# Show usage
if re.search(r'-+(h|help)', str(sys.argv), re.IGNORECASE):
show_usage(script_name)
exit_script()
# Show usage
if re.search(r'-+(h|help)', str(sys.argv), re.IGNORECASE):
show_usage(script_name)
exit_script()
# Start cloning/imaging
if run_mode in ('clone', 'image'):
menu_ddrescue(source_path, dest_path, run_mode)
else:
if not re.search(r'^-*(h|help\?)', run_mode, re.IGNORECASE):
print_error('Invalid mode.')
# Start cloning/imaging
if run_mode in ('clone', 'image'):
menu_ddrescue(source_path, dest_path, run_mode)
else:
if not re.search(r'^-*(h|help\?)', run_mode, re.IGNORECASE):
print_error('Invalid mode.')
# Done
print_standard('\nDone.')
pause("Press Enter to exit...")
exit_script()
except GenericAbort:
abort()
except GenericError as ge:
msg = 'Generic Error'
if str(ge):
msg = str(ge)
print_error(msg)
abort()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
pause("Press Enter to exit...")
tmux_switch_client()
exit_script()
except GenericAbort:
abort()
except GenericError as ge:
msg = 'Generic Error'
if str(ge):
msg = str(ge)
print_error(msg)
abort()
except SystemExit as sys_exit:
tmux_switch_client()
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=4 sw=4 ts=4
# vim: sts=2 sw=2 ts=2

View file

@ -1,39 +0,0 @@
#!/bin/python3
#
## Wizard Kit: SMART attributes display for ddrescue TUI
import os
import sys
import time
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.hw_diags import *
#init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
dev_path = sys.argv[1]
devs = scan_disks(True, dev_path)
# Warn if SMART unavailable
if dev_path not in devs:
print_error('SMART data not available')
exit_script()
# Initial screen
dev = devs[dev_path]
clear_screen()
show_disk_details(dev, only_attributes=True)
# Done
exit_script()
except SystemExit:
pass
except:
major_exception()
# vim: sts=4 sw=4 ts=4

View file

@ -0,0 +1,186 @@
# Wizard Kit: Debug - HW Diagnostics
import base64
import requests
from functions.common import *
def debug_report_cpu(cpu_obj):
"""Generate report for CpuObj, returns list."""
report = []
# CPU Info
report.append('CPU: {}'.format(cpu_obj.name))
report.append('lscpu:')
for k, v in sorted(cpu_obj.lscpu.items()):
report.append(' {}: {}'.format(k, v))
# Tests
report.append('Tests:')
for k, v in cpu_obj.tests.items():
report.extend(debug_report_test(v, k))
# Done
return report
def debug_report_disk(disk_obj):
"""Generate report for DiskObj, returns list."""
report = []
expand = [
'lsblk',
'nvme_attributes',
'nvme_smart_notes',
'smart_attributes',
'smart_self_test',
'smartctl',
]
skip = [
'add_nvme_smart_note',
'calc_io_dd_values',
'check_attributes',
'check_smart_self_test',
'description',
'disable_test',
'generate_attribute_report',
'generate_disk_report',
'get_details',
'get_size',
'get_smart_details',
'name',
'safety_check',
'tests',
]
# Disk Info
report.append('Disk: {} {}'.format(
disk_obj.name, disk_obj.description))
for a in dir(disk_obj):
if a.startswith('_') or a in skip:
continue
if a in expand:
report.append('{}:'.format(a))
attr = getattr(disk_obj, a)
try:
for k, v in sorted(attr.items()):
report.append(' {}: {}'.format(k, v))
except Exception:
# Ignore
pass
else:
report.append('{}: {}'.format(a, getattr(disk_obj, a)))
# Tests
report.append('Tests:')
for k, v in disk_obj.tests.items():
report.extend(debug_report_test(v, k))
# Done
return report
def debug_report_state(state):
"""Generate report for State, returns list."""
report = []
# Devs
report.append('CPU: {}'.format(state.cpu))
report.append('Disks: {}'.format(state.disks))
# Settings
report.append('Progress Out: {}'.format(state.progress_out))
report.append('Quick Mode: {}'.format(state.quick_mode))
# Tests
report.append('Tests:')
for k, v in state.tests.items():
report.append(' {}:'.format(k))
for k2, v2 in sorted(v.items()):
report.append(' {}: {}'.format(k2, v2))
# tmux
if hasattr(state, 'tmux_layout'):
report.append('tmux Layout:')
for k, v in state.tmux_layout.items():
report.append(' {}: {}'.format(k, str(v)))
if hasattr(state, 'panes'):
report.append('tmux Panes:')
for k, v in state.panes.items():
report.append(' {}: {}'.format(k, str(v)))
# Done
return report
def debug_report_test(test_obj, test_name):
"""Generate report for TestObj, returns list."""
report = [' {}:'.format(test_name)]
skip = ['update_status']
# Attributes
for a in [a for a in dir(test_obj) if not a.startswith('_')]:
if a in skip:
continue
report.append(' {}: {}'.format(a, getattr(test_obj, a)))
# Done
return report
def save_debug_reports(state, global_vars):
"""Save debug reports if possible."""
debug_dest = '{}/debug'.format(global_vars['LogDir'])
os.makedirs(debug_dest, exist_ok=True)
# State
with open('{}/state.report'.format(debug_dest), 'a') as f:
for line in debug_report_state(state):
f.write('{}\n'.format(line))
# CPU
with open('{}/cpu.report'.format(debug_dest), 'a') as f:
for line in debug_report_cpu(state.cpu):
f.write('{}\n'.format(line))
# Disk(s)
for disk in state.disks:
with open('{}/disk_{}.report'.format(debug_dest, disk.name), 'a') as f:
for line in debug_report_disk(disk):
f.write('{}\n'.format(line))
def upload_logdir(global_vars, reason='Crash'):
"""Upload compressed LogDir to CRASH_SERVER."""
source = global_vars['LogDir']
source = source[source.rfind('/')+1:]
dest = 'HW-Diags_{reason}_{Date-Time}.txz'.format(
reason=reason,
**global_vars,
)
data = None
# Compress LogDir
os.chdir('{}/..'.format(global_vars['LogDir']))
cmd = ['tar', 'caf', dest, source]
run_program(cmd)
# Read file
with open(dest, 'rb') as f:
data = f.read()
# Upload data
url = '{}/{}'.format(CRASH_SERVER['Url'], dest)
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 GenericError
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -4,54 +4,55 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.repairs import *
init_global_vars()
os.system('title {}: DISM helper Tool'.format(KIT_NAME_FULL))
set_log_file('DISM Helper.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
disabled = bool(global_vars['OS']['Version'] not in ('8', '8.1', '10'))
options = [
{'Name': 'Check Health', 'Repair': False, 'Disabled': disabled},
{'Name': 'Restore Health', 'Repair': True, 'Disabled': disabled}]
actions = [{'Name': 'Quit', 'Letter': 'Q'}]
selection = menu_select(
'{}: DISM Menu\n'.format(KIT_NAME_FULL),
main_entries=options,
action_entries=actions)
print_info('{}: DISM Menu\n'.format(KIT_NAME_FULL))
if selection == 'Q':
abort()
elif selection.isnumeric():
repair = options[int(selection)-1]['Repair']
if repair:
message='DISM RestoreHealth...'
else:
message='DISM ScanHealth...'
try_and_print(message=message, function=run_dism,
cs='No corruption', ns='Corruption detected',
other_results=other_results, repair=repair)
else:
abort()
try:
stay_awake()
clear_screen()
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
disabled = bool(global_vars['OS']['Version'] not in ('8', '8.1', '10'))
options = [
{'Name': 'Check Health', 'Repair': False, 'Disabled': disabled},
{'Name': 'Restore Health', 'Repair': True, 'Disabled': disabled}]
actions = [{'Name': 'Quit', 'Letter': 'Q'}]
selection = menu_select(
'{}: DISM Menu\n'.format(KIT_NAME_FULL),
main_entries=options,
action_entries=actions)
print_info('{}: DISM Menu\n'.format(KIT_NAME_FULL))
if selection == 'Q':
abort()
elif selection.isnumeric():
repair = options[int(selection)-1]['Repair']
if repair:
message='DISM RestoreHealth...'
else:
message='DISM ScanHealth...'
try_and_print(message=message, function=run_dism,
cs='No corruption', ns='Corruption detected',
other_results=other_results, repair=repair)
else:
abort()
# Done
print_success('Done.')
pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_success('Done.')
pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -6,61 +6,68 @@ from borrowed import acpi
from functions.common import *
from os import environ
# Variables
# STATIC VARIABLES
SLMGR = r'{}\System32\slmgr.vbs'.format(environ.get('SYSTEMROOT'))
def activate_with_bios():
"""Attempt to activate Windows with a key stored in the BIOS."""
# Code borrowed from https://github.com/aeruder/get_win8key
#####################################################
#script to query windows 8.x OEM key from PC firmware
#ACPI -> table MSDM -> raw content -> byte offset 56 to end
#ck, 03-Jan-2014 (christian@korneck.de)
#####################################################
bios_key = None
table = b"MSDM"
if acpi.FindAcpiTable(table) is True:
rawtable = acpi.GetAcpiTable(table)
#http://msdn.microsoft.com/library/windows/hardware/hh673514
#byte offset 36 from beginning \
# = Microsoft 'software licensing data structure' \
# / 36 + 20 bytes offset from beginning = Win Key
bios_key = rawtable[56:len(rawtable)].decode("utf-8")
if bios_key is None:
raise BIOSKeyNotFoundError
"""Attempt to activate Windows with a key stored in the BIOS."""
# Code borrowed from https://github.com/aeruder/get_win8key
#####################################################
#script to query windows 8.x OEM key from PC firmware
#ACPI -> table MSDM -> raw content -> byte offset 56 to end
#ck, 03-Jan-2014 (christian@korneck.de)
#####################################################
bios_key = None
table = b"MSDM"
if acpi.FindAcpiTable(table) is True:
rawtable = acpi.GetAcpiTable(table)
#http://msdn.microsoft.com/library/windows/hardware/hh673514
#byte offset 36 from beginning \
# = Microsoft 'software licensing data structure' \
# / 36 + 20 bytes offset from beginning = Win Key
bios_key = rawtable[56:len(rawtable)].decode("utf-8")
if bios_key is None:
raise BIOSKeyNotFoundError
# Install Key
cmd = ['cscript', '//nologo', SLMGR, '/ipk', bios_key]
subprocess.run(cmd, check=False)
sleep(5)
# Install Key
cmd = ['cscript', '//nologo', SLMGR, '/ipk', bios_key]
subprocess.run(cmd, check=False)
sleep(5)
# Attempt activation
cmd = ['cscript', '//nologo', SLMGR, '/ato']
subprocess.run(cmd, check=False)
sleep(5)
# Attempt activation
cmd = ['cscript', '//nologo', SLMGR, '/ato']
subprocess.run(cmd, check=False)
sleep(5)
# Check status
if not windows_is_activated():
raise Exception('Activation Failed')
# Check status
if not windows_is_activated():
raise Exception('Activation Failed')
def get_activation_string():
"""Get activation status, returns str."""
act_str = subprocess.run(
['cscript', '//nologo', SLMGR, '/xpr'], check=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
act_str = act_str.stdout.decode()
act_str = act_str.splitlines()
act_str = act_str[1].strip()
return act_str
"""Get activation status, returns str."""
act_str = subprocess.run(
['cscript', '//nologo', SLMGR, '/xpr'], check=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
act_str = act_str.stdout.decode()
act_str = act_str.splitlines()
act_str = act_str[1].strip()
return act_str
def windows_is_activated():
"""Check if Windows is activated via slmgr.vbs and return bool."""
activation_string = subprocess.run(
['cscript', '//nologo', SLMGR, '/xpr'], check=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
activation_string = activation_string.stdout.decode()
"""Check if Windows is activated via slmgr.vbs and return bool."""
activation_string = subprocess.run(
['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)
return bool(activation_string and 'permanent' in activation_string)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -4,202 +4,216 @@ import ctypes
from functions.disk import *
# Regex
REGEX_BAD_PATH_NAMES = re.compile(
r'([<>:"/\|\?\*]'
r'|^(CON|PRN|AUX|NUL|COM\d*|LPT\d*)$)'
r'|^\s+'
r'|[\s\.]+$',
re.IGNORECASE)
r'([<>:"/\|\?\*]'
r'|^(CON|PRN|AUX|NUL|COM\d*|LPT\d*)$)'
r'|^\s+'
r'|[\s\.]+$',
re.IGNORECASE)
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
"""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',
'{}:\\'.format(par['Letter']),
par['Image Path'],
par['Image Name'], # Image name
par['Image Name'], # Image description
'--compress=none',
]
dest_dir = re.sub(r'(.*)\\.*$', r'\1', par['Image Path'], re.IGNORECASE)
os.makedirs(dest_dir, exist_ok=True)
run_program(cmd)
cmd = [
global_vars['Tools']['wimlib-imagex'],
'capture',
'{}:\\'.format(par['Letter']),
par['Image Path'],
par['Image Name'], # Image name
par['Image Name'], # Image description
'--compress=none',
]
dest_dir = re.sub(r'(.*)\\.*$', r'\1', par['Image Path'], re.IGNORECASE)
os.makedirs(dest_dir, exist_ok=True)
run_program(cmd)
def fix_path(path):
"""Replace invalid filename characters with underscores."""
local_drive = path[1:2] == ':'
new_path = REGEX_BAD_PATH_NAMES.sub('_', path)
if local_drive:
new_path = '{}:{}'.format(new_path[0:1], new_path[2:])
return new_path
"""Replace invalid filename characters with underscores."""
local_drive = path[1:2] == ':'
new_path = REGEX_BAD_PATH_NAMES.sub('_', path)
if local_drive:
new_path = '{}:{}'.format(new_path[0:1], new_path[2:])
return new_path
def get_volume_display_name(mountpoint):
"""Get display name from volume mountpoint and label, returns str."""
name = mountpoint
try:
kernel32 = ctypes.windll.kernel32
vol_name_buffer = ctypes.create_unicode_buffer(1024)
fs_name_buffer = ctypes.create_unicode_buffer(1024)
serial_number = None
max_component_length = None
file_system_flags = None
"""Get display name from volume mountpoint and label, returns str."""
name = mountpoint
try:
kernel32 = ctypes.windll.kernel32
vol_name_buffer = ctypes.create_unicode_buffer(1024)
fs_name_buffer = ctypes.create_unicode_buffer(1024)
serial_number = None
max_component_length = None
file_system_flags = None
vol_info = kernel32.GetVolumeInformationW(
ctypes.c_wchar_p(mountpoint),
vol_name_buffer,
ctypes.sizeof(vol_name_buffer),
serial_number,
max_component_length,
file_system_flags,
fs_name_buffer,
ctypes.sizeof(fs_name_buffer)
)
vol_info = kernel32.GetVolumeInformationW(
ctypes.c_wchar_p(mountpoint),
vol_name_buffer,
ctypes.sizeof(vol_name_buffer),
serial_number,
max_component_length,
file_system_flags,
fs_name_buffer,
ctypes.sizeof(fs_name_buffer)
)
name = '{} "{}"'.format(name, vol_name_buffer.value)
except:
pass
name = '{} "{}"'.format(name, vol_name_buffer.value)
except:
pass
return name
return name
def prep_disk_for_backup(destination, disk, backup_prefix):
"""Gather details about the disk and its partitions.
"""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."""
disk['Clobber Risk'] = []
width = len(str(len(disk['Partitions'])))
This includes partitions that can't be backed up,
whether backups already exist on the BACKUP_SERVER,
partition names/sizes/used space, etc."""
disk['Clobber Risk'] = []
width = len(str(len(disk['Partitions'])))
# Get partition totals
disk['Bad Partitions'] = [par['Number'] for par in disk['Partitions']
if is_bad_partition(par)]
num_valid_partitions = len(disk['Partitions']) - len(disk['Bad Partitions'])
disk['Valid Partitions'] = num_valid_partitions
if disk['Valid Partitions'] <= 0:
print_error('ERROR: No partitions can be backed up for this disk')
raise GenericAbort
# Get partition totals
disk['Bad Partitions'] = [par['Number'] for par in disk['Partitions']
if is_bad_partition(par)]
num_valid_partitions = len(disk['Partitions']) - len(disk['Bad Partitions'])
disk['Valid Partitions'] = num_valid_partitions
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(
num = par['Number'],
width = width,
size = par['Size'],
fs = par['FileSystem'])
# Prep partitions
for par in disk['Partitions']:
display = '{size} {fs}'.format(
num = par['Number'],
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(
display = display,
q = '"' if par['Name'] != '' else '',
name = par['Name'],
desc = par['Description'],
os = par['OS'])
else:
# Update info for WIM capturing
par['Image Name'] = par['Name'] if par['Name'] else 'Unknown'
if 'IP' in destination:
par['Image Path'] = r'\\{}\{}\{}'.format(
destination['IP'], destination['Share'], backup_prefix)
else:
par['Image Path'] = r'{}:\{}'.format(
destination['Letter'], backup_prefix)
par['Image Path'] += r'\{}_{}.wim'.format(
par['Number'], par['Image Name'])
par['Image Path'] = fix_path(par['Image Path'])
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(
display = display,
q = '"' if par['Name'] != '' else '',
name = par['Name'],
desc = par['Description'],
os = par['OS'])
else:
# Update info for WIM capturing
par['Image Name'] = par['Name'] if par['Name'] else 'Unknown'
if 'IP' in destination:
par['Image Path'] = r'\\{}\{}\{}'.format(
destination['IP'], destination['Share'], backup_prefix)
else:
par['Image Path'] = r'{}:\{}'.format(
destination['Letter'], backup_prefix)
par['Image Path'] += r'\{}_{}.wim'.format(
par['Number'], par['Image Name'])
par['Image Path'] = fix_path(par['Image Path'])
# Check for existing backups
par['Image Exists'] = os.path.exists(par['Image Path'])
if par['Image Exists']:
disk['Clobber Risk'].append(par['Number'])
display = '+ {}'.format(display)
else:
display = ' {}'.format(display)
# Check for existing backups
par['Image Exists'] = os.path.exists(par['Image Path'])
if par['Image Exists']:
disk['Clobber Risk'].append(par['Number'])
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'],
q = '"' if par['Name'] != '' else '',
name = par['Name'])
# For all partitions
par['Display String'] = display
# Append rest of Display String for valid/clobber partitions
display += ' (Used: {used})\t{q}{name}{q}'.format(
used = par['Used Space'],
q = '"' if par['Name'] != '' else '',
name = par['Name'])
# For all partitions
par['Display String'] = display
# Set description for bad partitions
warnings = '\n'
if disk['Bad Partitions']:
warnings += '{} * Unsupported filesystem{}\n'.format(
COLORS['YELLOW'], COLORS['CLEAR'])
if disk['Clobber Risk']:
warnings += '{} + Backup exists on {}{}\n'.format(
COLORS['BLUE'], destination['Name'], COLORS['CLEAR'])
if disk['Bad Partitions'] or disk['Clobber Risk']:
warnings += '\n{}Marked partition(s) will NOT be backed up.{}\n'.format(
COLORS['YELLOW'], COLORS['CLEAR'])
disk['Backup Warnings'] = warnings
# Set description for bad partitions
warnings = '\n'
if disk['Bad Partitions']:
warnings += '{} * Unsupported filesystem{}\n'.format(
COLORS['YELLOW'], COLORS['CLEAR'])
if disk['Clobber Risk']:
warnings += '{} + Backup exists on {}{}\n'.format(
COLORS['BLUE'], destination['Name'], COLORS['CLEAR'])
if disk['Bad Partitions'] or disk['Clobber Risk']:
warnings += '\n{}Marked partition(s) will NOT be backed up.{}\n'.format(
COLORS['YELLOW'], COLORS['CLEAR'])
disk['Backup Warnings'] = warnings
def select_backup_destination(auto_select=True):
"""Select a backup destination from a menu, returns server dict."""
destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
actions = [
{'Name': 'Main Menu', 'Letter': 'M'},
]
"""Select a backup destination from a menu, returns server dict."""
destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
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):
# Skip current OS drive
pass
elif 'fixed' in d.opts:
# Skip DVD, etc
destinations.append({
'Name': 'Local Disk - {}'.format(
get_volume_display_name(d.mountpoint)),
'Letter': re.sub(r'^(\w):\\.*$', r'\1', d.mountpoint),
})
# Add local disks
for d in psutil.disk_partitions():
if re.search(
r'^{}'.format(global_vars['Env']['SYSTEMDRIVE']),
d.mountpoint,
re.IGNORECASE):
# Skip current OS drive
pass
elif 'fixed' in d.opts:
# Skip DVD, etc
destinations.append({
'Name': 'Local Disk - {}'.format(
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:
dest['Usage'] = shutil.disk_usage(r'\\{IP}\{Share}'.format(**dest))
else:
dest['Usage'] = shutil.disk_usage('{}:\\'.format(dest['Letter']))
dest['Free Space'] = human_readable_size(dest['Usage'].free)
dest['Display Name'] = '{Name} ({Free Space} available)'.format(**dest)
# Bail
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,
action_entries = actions)
if selection == 'M':
raise GenericAbort
# Size check
for dest in destinations:
if 'IP' in dest:
dest['Usage'] = shutil.disk_usage(r'\\{IP}\{Share}'.format(**dest))
else:
return destinations[int(selection)-1]
dest['Usage'] = shutil.disk_usage('{}:\\'.format(dest['Letter']))
dest['Free Space'] = human_readable_size(dest['Usage'].free)
dest['Display Name'] = '{Name} ({Free Space} available)'.format(**dest)
# Bail
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,
action_entries = actions)
if selection == 'M':
raise GenericAbort
else:
return destinations[int(selection)-1]
def verify_wim_backup(partition):
"""Verify WIM integrity."""
if not os.path.exists(partition['Image Path']):
raise PathNotFoundError
cmd = [
global_vars['Tools']['wimlib-imagex'],
'verify',
partition['Image Path'],
'--nocheck',
]
run_program(cmd)
"""Verify WIM integrity."""
if not os.path.exists(partition['Image Path']):
raise PathNotFoundError
cmd = [
global_vars['Tools']['wimlib-imagex'],
'verify',
partition['Image Path'],
'--nocheck',
]
run_program(cmd)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,508 +1,470 @@
# Wizard Kit: Functions - Browsers
from functions.common import *
from operator import itemgetter
from settings.browsers import *
# Define other_results for later try_and_print
browser_data = {}
other_results = {
'Error': {
'MultipleInstallationsError': 'Multiple installations detected',
},
'Warning': {
'NotInstalledError': 'Not installed',
'NoProfilesError': 'No profiles found',
}
'Error': {
'MultipleInstallationsError': 'Multiple installations detected',
},
'Warning': {
'NotInstalledError': 'Not installed',
'NoProfilesError': 'No profiles found',
}
}
# Regex
REGEX_BACKUP = re.compile(
r'\.\w*bak.*',
re.IGNORECASE)
REGEX_CHROMIUM_PROFILE = re.compile(
r'^(Default|Profile)',
re.IGNORECASE)
REGEX_CHROMIUM_ITEMS = re.compile(
r'^(Bookmarks|Cookies|Favicons|Google Profile'
r'|History|Login Data|Top Sites|TransportSecurity'
r'|Visited Links|Web Data)',
re.IGNORECASE)
REGEX_MOZILLA = re.compile(
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
r'|key3.db|logins.json|persdict.dat)$',
re.IGNORECASE)
# STATIC VARIABLES
DEFAULT_HOMEPAGE = 'https://www.google.com/'
IE_GALLERY = 'https://www.microsoft.com/en-us/iegallery'
MOZILLA_PREFS = {
'browser.search.defaultenginename': '"Google"',
'browser.search.defaultenginename.US': '"Google"',
'browser.search.geoSpecificDefaults': 'false',
'browser.startup.homepage': '"{}"'.format(DEFAULT_HOMEPAGE),
'extensions.ui.lastCategory': '"addons://list/extension"',
}
UBO_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm?hl=en'
UBO_CHROME_REG = r'Software\Wow6432Node\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm'
UBO_EXTRA_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin-extra/pgdnlhfefecpicbbihgmbmffkjpaplco?hl=en'
UBO_EXTRA_CHROME_REG = r'Software\Wow6432Node\Google\Chrome\Extensions\pgdnlhfefecpicbbihgmbmffkjpaplco'
UBO_MOZILLA = 'https://addons.mozilla.org/en-us/firefox/addon/ublock-origin/'
UBO_MOZZILA_PATH = r'{}\Mozilla Firefox\distribution\extensions\ublock_origin.xpi'.format(os.environ.get('PROGRAMFILES'))
UBO_MOZILLA_REG = r'Software\Mozilla\Firefox\Extensions'
UBO_MOZILLA_REG_NAME = 'uBlock0@raymondhill.net'
UBO_OPERA = 'https://addons.opera.com/en/extensions/details/ublock/?display=en'
SUPPORTED_BROWSERS = {
'Internet Explorer': {
'base': 'ie',
'exe_name': 'iexplore.exe',
'rel_install_path': 'Internet Explorer',
'user_data_path': r'{USERPROFILE}\Favorites',
},
'Google Chrome': {
'base': 'chromium',
'exe_name': 'chrome.exe',
'rel_install_path': r'Google\Chrome\Application',
'user_data_path': r'{LOCALAPPDATA}\Google\Chrome\User Data',
},
'Google Chrome Canary': {
'base': 'chromium',
'exe_name': 'chrome.exe',
'rel_install_path': r'Google\Chrome SxS\Application',
'user_data_path': r'{LOCALAPPDATA}\Google\Chrome SxS\User Data',
},
'Mozilla Firefox': {
'base': 'mozilla',
'exe_name': 'firefox.exe',
'rel_install_path': 'Mozilla Firefox',
'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles',
},
'Mozilla Firefox Dev': {
'base': 'mozilla',
'exe_name': 'firefox.exe',
'rel_install_path': 'Firefox Developer Edition',
'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles',
},
'Opera': {
'base': 'chromium',
'exe_name': 'launcher.exe',
'rel_install_path': 'Opera',
'user_data_path': r'{APPDATA}\Opera Software\Opera Stable',
},
'Opera Beta': {
'base': 'chromium',
'exe_name': 'launcher.exe',
'rel_install_path': 'Opera beta',
'user_data_path': r'{APPDATA}\Opera Software\Opera Next',
},
'Opera Dev': {
'base': 'chromium',
'exe_name': 'launcher.exe',
'rel_install_path': 'Opera developer',
'user_data_path': r'{APPDATA}\Opera Software\Opera Developer',
},
}
def archive_all_users():
"""Create backups for all browsers for all users."""
users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE'])
user_envs = []
"""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})
# 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 = valid_user and os.path.exists(appdata_local)
valid_user = valid_user and 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})\{Date}'.format(
**global_vars, **global_vars['Env'])
archive = r'{}\{}.7z'.format(dest, name)
os.makedirs(dest, exist_ok=True)
cmd = [
# 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',
'-mhe=on', '-p{}'.format(ARCHIVE_PASSWORD),
archive, source]
run_program(cmd)
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})\{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)
def backup_browsers():
"""Create backup of all detected browser profiles."""
for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]:
try_and_print(message='{}...'.format(name),
function=archive_browser, name=name)
"""Create backup of all detected browser profiles."""
for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]:
try_and_print(message='{}...'.format(name),
function=archive_browser, name=name)
def clean_chromium_profile(profile):
"""Renames profile, creates a new folder, and copies the user data to it."""
if profile is None:
raise Exception
backup_path = '{path}_{Date}.bak'.format(
path=profile['path'], **global_vars)
backup_path = non_clobber_rename(backup_path)
shutil.move(profile['path'], backup_path)
os.makedirs(profile['path'], exist_ok=True)
"""Recreate profile with only the essential user data.
This is done by renaming the existing profile, creating a new folder
with the original name, then copying the essential files from the
backup folder. This way the original state is preserved in case
something goes wrong.
"""
if profile is None:
raise Exception
backup_path = '{path}_{Date}.bak'.format(
path=profile['path'], **global_vars)
backup_path = non_clobber_rename(backup_path)
shutil.move(profile['path'], backup_path)
os.makedirs(profile['path'], exist_ok=True)
# Restore essential files from backup_path
for entry in os.scandir(backup_path):
if REGEX_CHROMIUM_ITEMS.search(entry.name):
shutil.copy(entry.path, r'{}\{}'.format(
profile['path'], entry.name))
# Restore essential files from backup_path
for entry in os.scandir(backup_path):
if REGEX_CHROMIUM_ITEMS.search(entry.name):
shutil.copy(entry.path, r'{}\{}'.format(
profile['path'], entry.name))
def clean_internet_explorer(**kwargs):
"""Uses the built-in function to reset IE and sets the homepage.
"""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)
key = r'Software\Microsoft\Internet Explorer\Main'
NOTE: kwargs set but unused as a workaround."""
kill_process('iexplore.exe')
run_program(['rundll32.exe', 'inetcpl.cpl,ResetIEtoDefaults'], check=False)
key = r'Software\Microsoft\Internet Explorer\Main'
# Set homepage
with winreg.OpenKey(HKCU, key, access=winreg.KEY_WRITE) as _key:
winreg.SetValueEx(_key, 'Start Page', 0,
winreg.REG_SZ, DEFAULT_HOMEPAGE)
try:
winreg.DeleteValue(_key, 'Secondary Start Pages')
except FileNotFoundError:
pass
# Set homepage
with winreg.OpenKey(HKCU, key, access=winreg.KEY_WRITE) as _key:
winreg.SetValueEx(_key, 'Start Page', 0,
winreg.REG_SZ, DEFAULT_HOMEPAGE)
try:
winreg.DeleteValue(_key, 'Secondary Start Pages')
except FileNotFoundError:
pass
def clean_mozilla_profile(profile):
"""Renames profile, creates a new folder, and copies the user data to it."""
if profile is None:
raise Exception
backup_path = '{path}_{Date}.bak'.format(
path=profile['path'], **global_vars)
backup_path = non_clobber_rename(backup_path)
shutil.move(profile['path'], backup_path)
homepages = []
os.makedirs(profile['path'], exist_ok=True)
"""Recreate profile with only the essential user data.
# Restore essential files from backup_path
for entry in os.scandir(backup_path):
if REGEX_MOZILLA.search(entry.name):
if entry.is_dir():
shutil.copytree(entry.path, r'{}\{}'.format(
profile['path'], entry.name))
else:
shutil.copy(entry.path, r'{}\{}'.format(
profile['path'], entry.name))
This is done by renaming the existing profile, creating a new folder
with the original name, then copying the essential files from the
backup folder. This way the original state is preserved in case
something goes wrong.
"""
if profile is None:
raise Exception
backup_path = '{path}_{Date}.bak'.format(
path=profile['path'], **global_vars)
backup_path = non_clobber_rename(backup_path)
shutil.move(profile['path'], backup_path)
homepages = []
os.makedirs(profile['path'], exist_ok=True)
# Restore essential files from backup_path
for entry in os.scandir(backup_path):
if REGEX_MOZILLA.search(entry.name):
if entry.is_dir():
shutil.copytree(entry.path, r'{}\{}'.format(
profile['path'], entry.name))
else:
shutil.copy(entry.path, r'{}\{}'.format(
profile['path'], entry.name))
# Set profile defaults
with open(r'{path}\prefs.js'.format(**profile), 'a', encoding='ascii') as f:
for k, v in MOZILLA_PREFS.items():
f.write('user_pref("{}", {});\n'.format(k, v))
# Set profile defaults
with open(r'{path}\prefs.js'.format(**profile), 'a', encoding='ascii') as f:
for k, v in MOZILLA_PREFS.items():
f.write('user_pref("{}", {});\n'.format(k, v))
def get_browser_details(name):
"""Get installation status and profile details for all supported browsers."""
browser = SUPPORTED_BROWSERS[name].copy()
"""Get installation 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'])
# 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
for install_path in ['LOCALAPPDATA', 'PROGRAMFILES(X86)', 'PROGRAMFILES']:
test_path = r'{install_path}\{rel_install_path}\{exe_name}'.format(
install_path = global_vars['Env'].get(install_path, ''),
**browser)
if os.path.exists(test_path):
num_installs += 1
exe_path = test_path
# Find executable (if multiple files are found, the last one is used)
exe_path = None
num_installs = 0
for install_path in ['LOCALAPPDATA', 'PROGRAMFILES(X86)', 'PROGRAMFILES']:
test_path = r'{install_path}\{rel_install_path}\{exe_name}'.format(
install_path = global_vars['Env'].get(install_path, ''),
**browser)
if os.path.exists(test_path):
num_installs += 1
exe_path = test_path
# Find profile(s)
profiles = []
if browser['base'] == 'ie':
profiles.append({'name': 'Default', 'path': None})
elif 'Google Chrome' in name:
profiles.extend(
get_chromium_profiles(
search_path=browser['user_data_path']))
elif browser['base'] == 'mozilla':
dev = 'Dev' in name
profiles.extend(
get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev))
if exe_path and not dev and len(profiles) == 0:
# e.g. If Firefox is installed but no profiles were found.
## Rename profiles.ini and create a new default profile
profiles_ini_path = browser['user_data_path'].replace(
'Profiles', 'profiles.ini')
if os.path.exists(profiles_ini_path):
backup_path = '{path}_{Date}.bak'.format(
path=profiles_ini_path, **global_vars)
backup_path = non_clobber_rename(backup_path)
shutil.move(profiles_ini_path, backup_path)
run_program([exe_path, '-createprofile', 'default'], check=False)
profiles.extend(
get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev))
# Find profile(s)
profiles = []
if browser['base'] == 'ie':
profiles.append({'name': 'Default', 'path': None})
elif 'Google Chrome' in name:
profiles.extend(
get_chromium_profiles(
search_path=browser['user_data_path']))
elif browser['base'] == 'mozilla':
dev = 'Dev' in name
profiles.extend(
get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev))
if exe_path and not dev and len(profiles) == 0:
# e.g. If Firefox is installed but no profiles were found.
## Rename profiles.ini and create a new default profile
profiles_ini_path = browser['user_data_path'].replace(
'Profiles', 'profiles.ini')
if os.path.exists(profiles_ini_path):
backup_path = '{path}_{Date}.bak'.format(
path=profiles_ini_path, **global_vars)
backup_path = non_clobber_rename(backup_path)
shutil.move(profiles_ini_path, backup_path)
run_program([exe_path, '-createprofile', 'default'], check=False)
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']})
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
profiles[0]['homepages'] = get_ie_homepages()
elif browser['base'] == 'mozilla':
for profile in profiles:
prefs_path = r'{path}\prefs.js'.format(**profile)
profile['homepages'] = get_mozilla_homepages(prefs_path=prefs_path)
# Get homepages
if browser['base'] == 'ie':
# IE is set to only have one profile above
profiles[0]['homepages'] = get_ie_homepages()
elif browser['base'] == 'mozilla':
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,
})
# 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
elif num_installs > 1 and browser['base'] != 'ie':
raise MultipleInstallationsError
# Raise installation warnings (if any)
if num_installs == 0:
raise NotInstalledError
elif num_installs > 1 and browser['base'] != 'ie':
raise MultipleInstallationsError
def get_chromium_profiles(search_path):
"""Find any chromium-style profiles and return as a list of dicts."""
profiles = []
try:
for entry in os.scandir(search_path):
if entry.is_dir() and REGEX_CHROMIUM_PROFILE.search(entry.name):
profiles.append(entry)
REGEX_PROFILE_BACKUP = r'\.\w+bak.*'
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception:
pass
"""Find any chromium-style profiles and return as a list of dicts."""
profiles = []
try:
for entry in os.scandir(search_path):
if entry.is_dir() and REGEX_CHROMIUM_PROFILE.search(entry.name):
profiles.append(entry)
REGEX_PROFILE_BACKUP = r'\.\w+bak.*'
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception:
pass
return profiles
return profiles
def get_ie_homepages():
"""Read homepages from the registry and return as a list."""
homepages = []
main_page = ''
extra_pages = []
key = r'Software\Microsoft\Internet Explorer\Main'
with winreg.OpenKey(HKCU, key) as _key:
try:
main_page = winreg.QueryValueEx(_key, 'Start Page')[0]
except FileNotFoundError:
pass
try:
extra_pages = winreg.QueryValueEx(_key, 'Secondary Start Pages')[0]
except FileNotFoundError:
pass
if main_page != '':
homepages.append(main_page)
if len(extra_pages) > 0:
homepages.extend(extra_pages)
"""Read homepages from the registry and return as a list."""
homepages = []
main_page = ''
extra_pages = []
key = r'Software\Microsoft\Internet Explorer\Main'
with winreg.OpenKey(HKCU, key) as _key:
try:
main_page = winreg.QueryValueEx(_key, 'Start Page')[0]
except FileNotFoundError:
pass
try:
extra_pages = winreg.QueryValueEx(_key, 'Secondary Start Pages')[0]
except FileNotFoundError:
pass
if main_page != '':
homepages.append(main_page)
if len(extra_pages) > 0:
homepages.extend(extra_pages)
# Remove all curly braces
homepages = [h.replace('{', '').replace('}', '') for h in homepages]
return homepages
# Remove all curly braces
homepages = [h.replace('{', '').replace('}', '') for h in homepages]
return homepages
def get_mozilla_homepages(prefs_path):
"""Read homepages from prefs.js and return as a list."""
homepages = []
try:
with open(prefs_path, 'r') as f:
search = re.search(
r'browser\.startup\.homepage", "([^"]*)"',
f.read(), re.IGNORECASE)
if search:
homepages = search.group(1).split('|')
except Exception:
pass
"""Read homepages from prefs.js and return as a list."""
homepages = []
try:
with open(prefs_path, 'r') as f:
search = re.search(
r'browser\.startup\.homepage", "([^"]*)"',
f.read(), re.IGNORECASE)
if search:
homepages = search.group(1).split('|')
except Exception:
pass
return homepages
return homepages
def get_mozilla_profiles(search_path, dev=False):
"""Find any mozilla-style profiles and return as a list of dicts."""
profiles = []
try:
for entry in os.scandir(search_path):
if entry.is_dir():
if 'dev-edition' in entry.name:
# NOTE: Not always present which can lead
# to Dev profiles being marked as non-Dev
## NOTE 2: It is possible that a non-Dev profile
## to be created with 'dev-edition' in the name.
## (It wouldn't make sense, but possible)
if dev:
profiles.append(entry)
elif not dev:
profiles.append(entry)
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception:
pass
"""Find any mozilla-style profiles and return as a list of dicts."""
profiles = []
try:
for entry in os.scandir(search_path):
if entry.is_dir():
if 'dev-edition' in entry.name:
# NOTE: Not always present which can lead
# to Dev profiles being marked as non-Dev
## NOTE 2: It is possible that a non-Dev profile
## to be created with 'dev-edition' in the name.
## (It wouldn't make sense, but possible)
if dev:
profiles.append(entry)
elif not dev:
profiles.append(entry)
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception:
pass
return profiles
return profiles
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:
if browser_data[browser]['profiles']:
print_standard(
'{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'),
end='', flush=True)
print_warning('Profile(s) detected but browser not installed',
timestamp=False)
else:
# Only warn if profile(s) are detected.
pass
"""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)
if not exe_path:
if browser_data[browser]['profiles']:
print_standard(
'{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'),
end='', flush=True)
print_warning('Profile(s) detected but browser not installed',
timestamp=False)
else:
# Only warn if profile(s) are detected.
pass
else:
# Set urls to open
urls = []
if browser_data[browser]['base'] == 'chromium':
if browser == 'Google Chrome':
# Check for system exensions
try:
winreg.QueryValue(HKLM, UBO_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_CHROME)
try:
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:
urls.append(UBO_OPERA)
else:
# Set urls to open
urls = []
if browser_data[browser]['base'] == 'chromium':
if browser == 'Google Chrome':
# Check for system exensions
try:
winreg.QueryValue(HKLM, UBO_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_CHROME)
try:
winreg.QueryValue(HKLM, UBO_EXTRA_CHROME_REG)
except FileNotFoundError:
urls.append(UBO_EXTRA_CHROME)
urls.append(UBO_CHROME)
urls.append(UBO_EXTRA_CHROME)
if len(urls) == 0:
urls = ['chrome://extensions']
elif 'Opera' in browser:
urls.append(UBO_OPERA)
else:
urls.append(UBO_CHROME)
urls.append(UBO_EXTRA_CHROME)
elif browser_data[browser]['base'] == 'mozilla':
# Check for system extensions
try:
with winreg.OpenKey(HKLM, UBO_MOZILLA_REG) as key:
winreg.QueryValueEx(key, UBO_MOZILLA_REG_NAME)
except FileNotFoundError:
urls = [UBO_MOZILLA]
else:
if os.path.exists(UBO_MOZZILA_PATH):
urls = ['about:addons']
else:
urls = [UBO_MOZILLA]
elif browser_data[browser]['base'] == 'mozilla':
# Check for system extensions
try:
with winreg.OpenKey(HKLM, UBO_MOZILLA_REG) as key:
winreg.QueryValueEx(key, UBO_MOZILLA_REG_NAME)
except FileNotFoundError:
urls = [UBO_MOZILLA]
else:
if os.path.exists(UBO_MOZZILA_PATH):
urls = ['about:addons']
else:
urls = [UBO_MOZILLA]
elif browser_data[browser]['base'] == 'ie':
urls.append(IE_GALLERY)
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).
# In other words, this isn't tracking the addon/extension's
# installation status.
try_and_print(message='{}...'.format(browser),
indent=indent, width=width,
cs='Started', function=popen_program,
cmd=[exe_path, *urls], check=False)
def is_installed(browser_name):
"""Checks if browser is installed based on exe_path, returns bool."""
browser_name = browser_name.replace(' Chromium', '')
return bool(browser_data.get(browser_name, {}).get('exe_path', False))
# 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).
# In other words, this isn't tracking the addon/extension's
# installation status.
try_and_print(message='{}...'.format(browser),
indent=indent, width=width,
cs='Done', function=function,
cmd=[exe_path, *urls], check=False)
def list_homepages(indent=8, width=32):
"""List current homepages for reference."""
"""List current homepages for reference."""
browser_list = [k for k, v in sorted(browser_data.items()) if v['exe_path']]
for browser in browser_list:
# Skip Chromium-based browsers
if browser_data[browser]['base'] == 'chromium':
print_info(
'{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'),
end='', flush=True)
print_warning('Not implemented', timestamp=False)
continue
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':
print_info(
'{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'),
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+'...'))
for profile in browser_data[browser].get('profiles', []):
name = profile.get('name', '?')
homepages = profile.get('homepages', [])
if len(homepages) == 0:
print_standard(
'{indent}{name:<{width}}'.format(
indent=' '*indent, width=width, name=name),
end='', flush=True)
print_warning('None found', timestamp=False)
else:
for page in homepages:
print_standard('{indent}{name:<{width}}{page}'.format(
indent=' '*indent, width=width, name=name, page=page))
def profile_present(browser_name):
"""Checks if a profile was detected for browser, returns bool."""
browser_name = browser_name.replace(' Chromium', '')
return bool(browser_data.get(browser_name, {}).get('profiles', False))
# All other browsers
print_info('{indent}{browser:<{width}}'.format(
indent=' '*indent, width=width, browser=browser+'...'))
for profile in browser_data[browser].get('profiles', []):
name = profile.get('name', '?')
homepages = profile.get('homepages', [])
if len(homepages) == 0:
print_standard(
'{indent}{name:<{width}}'.format(
indent=' '*indent, width=width, name=name),
end='', flush=True)
print_warning('None found', timestamp=False)
else:
for page in homepages:
print_standard('{indent}{name:<{width}}{page}'.format(
indent=' '*indent, width=width, name=name, page=page))
def reset_browsers(indent=8, width=32):
"""Reset all detected browsers to safe defaults."""
for browser in [k for k, v in sorted(browser_data.items()) if v['profiles']]:
print_info('{indent}{name}'.format(indent=' '*indent, name=browser))
for profile in browser_data[browser]['profiles']:
if browser_data[browser]['base'] == 'chromium':
function = clean_chromium_profile
elif browser_data[browser]['base'] == 'ie':
function = clean_internet_explorer
elif browser_data[browser]['base'] == 'mozilla':
function = clean_mozilla_profile
try_and_print(
message='{}...'.format(profile['name']),
indent=indent, width=width, function=function,
other_results=other_results, profile=profile)
"""Reset all detected browsers to safe defaults."""
browser_list = [k for k, v in sorted(browser_data.items()) if v['profiles']]
for browser in browser_list:
print_info('{indent}{name}'.format(indent=' '*indent, name=browser))
for profile in browser_data[browser]['profiles']:
if browser_data[browser]['base'] == 'chromium':
function = clean_chromium_profile
elif browser_data[browser]['base'] == 'ie':
function = clean_internet_explorer
elif browser_data[browser]['base'] == 'mozilla':
function = clean_mozilla_profile
try_and_print(
message='{}...'.format(profile['name']),
indent=indent, width=width, function=function,
other_results=other_results, profile=profile)
def scan_for_browsers(just_firefox=False, silent=False):
"""Scan system for any supported browsers."""
for name, details in sorted(SUPPORTED_BROWSERS.items()):
if just_firefox and details['base'] != 'mozilla':
continue
if silent:
try:
get_browser_details(name)
except Exception:
# Ignore errors in silent mode
pass
else:
try_and_print(message='{}...'.format(name),
function=get_browser_details, cs='Detected',
other_results=other_results, name=name)
def scan_for_browsers(just_firefox=False):
"""Scan system for any 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)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,129 +1,144 @@
# Wizard Kit: Functions - Cleanup
'''Wizard Kit: Functions - Cleanup'''
# pylint: disable=no-name-in-module,wildcard-import
# vim: sts=2 sw=2 ts=2
from functions.common import *
from functions.setup import *
from settings.cleanup import *
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)
"""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)
dest_name = r'{QuarantineDir}\AdwCleaner_{Date-Time}'.format(
**global_vars)
dest_name = non_clobber_rename(dest_name)
shutil.move(source_quarantine, dest_name)
# Quarantine
if os.path.exists(source_quarantine):
os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
dest_name = r'{QuarantineDir}\AdwCleaner_{Date-Time}'.format(
**global_vars)
dest_name = non_clobber_rename(dest_name)
shutil.move(source_quarantine, dest_name)
# Delete source folder if empty
delete_empty_folders(source_path)
# Delete source folder if empty
delete_empty_folders(source_path)
# Main folder
if os.path.exists(source_path):
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)
# Main folder
if os.path.exists(source_path):
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.
"""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.
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.
"""
backup_folder = r'{dest_folder}\CbsFix'.format(dest_folder=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)
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.
"""
backup_folder = r'{dest_folder}\CbsFix'.format(dest_folder=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):
# CbsPersist files
if entry.name.lower().startswith('cbspersist'):
dest_name = r'{}\{}'.format(temp_folder, entry.name)
dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name)
temp_path = r'{SYSTEMROOT}\Temp'.format(**global_vars['Env'])
for entry in os.scandir(temp_path):
# cab_ files
if entry.name.lower().startswith('cab_'):
dest_name = r'{}\{}'.format(temp_folder, entry.name)
dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name)
# Move files into temp folder
cbs_path = r'{SYSTEMROOT}\Logs\CBS'.format(**global_vars['Env'])
for entry in os.scandir(cbs_path):
# CbsPersist files
if entry.name.lower().startswith('cbspersist'):
dest_name = r'{}\{}'.format(temp_folder, entry.name)
dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name)
temp_path = r'{SYSTEMROOT}\Temp'.format(**global_vars['Env'])
for entry in os.scandir(temp_path):
# cab_ files
if entry.name.lower().startswith('cab_'):
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'],
'a', '-t7z', '-mx=3', '-bso0', '-bse0',
r'{}\CbsPersists.7z'.format(backup_folder),
r'{}\CbsPersist*'.format(temp_folder)]
run_program(cmd)
# Compress CbsPersist files with 7-Zip
cmd = [
global_vars['Tools']['SevenZip'],
'a', '-t7z', '-mx=3', '-bso0', '-bse0',
r'{}\CbsPersists.7z'.format(backup_folder),
r'{}\CbsPersist*'.format(temp_folder)]
run_program(cmd)
def cleanup_desktop():
"""Move known backup files and reports into the ClientDir."""
dest_folder = r'{LogDir}\Tools'.format(**global_vars)
os.makedirs(dest_folder, exist_ok=True)
"""Move known backup files and reports into the ClientDir."""
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
if re.search(r'^(JRT|RKill|sc-cleaner)', entry.name, re.IGNORECASE):
dest_name = r'{}\{}'.format(dest_folder, entry.name)
dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name)
desktop_path = r'{USERPROFILE}\Desktop'.format(**global_vars['Env'])
for entry in os.scandir(desktop_path):
if DESKTOP_ITEMS.search(entry.name):
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)
# 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 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)
# 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(folder_path)
except OSError:
pass
# Remove top folder
try:
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
"""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)
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
# 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)
"""Delete a registry value."""
access = winreg.KEY_ALL_ACCESS
with winreg.OpenKeyEx(hive, key, 0, access) as k:
winreg.DeleteValue(k, value)
def restore_default_uac():
"""Restores default UAC settings via the registry."""
if global_vars['OS']['Version'] == '10':
write_registry_settings(UAC_DEFAULTS_WIN10, all_users=True)
else:
# Haven't checked Win8 settings, only applying minimum set
write_registry_settings(UAC_DEFAULTS_WIN7, all_users=True)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=4 sw=4 ts=4
print("This file is not meant to be called directly.")

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,189 +0,0 @@
# Wizard Kit: Functions - Diagnostics
import ctypes
from functions.common import *
# STATIC VARIABLES
AUTORUNS_SETTINGS = {
r'Software\Sysinternals\AutoRuns': {
'checkvirustotal': 1,
'EulaAccepted': 1,
'shownomicrosoft': 1,
'shownowindows': 1,
'showonlyvirustotal': 1,
'submitvirustotal': 0,
'verifysignatures': 1,
},
r'Software\Sysinternals\AutoRuns\SigCheck': {
'EulaAccepted': 1,
},
r'Software\Sysinternals\AutoRuns\Streams': {
'EulaAccepted': 1,
},
r'Software\Sysinternals\AutoRuns\VirusTotal': {
'VirusTotalTermsAccepted': 1,
},
}
def check_connection():
"""Check if the system is online and optionally abort the script."""
while True:
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 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."""
extract_item('Autoruns', filter='autoruns*', silent=True)
# Update AutoRuns settings before running
for path, settings in AUTORUNS_SETTINGS.items():
winreg.CreateKey(HKCU, path)
with winreg.OpenKey(HKCU, path, access=winreg.KEY_WRITE) as key:
for name, value in settings.items():
winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
popen_program(global_vars['Tools']['AutoRuns'], minimized=True)
def run_hwinfo_sensors():
"""Run HWiNFO sensors."""
path = r'{BinDir}\HWiNFO'.format(**global_vars)
for bit in [32, 64]:
# Configure
source = r'{}\general.ini'.format(path)
dest = r'{}\HWiNFO{}.ini'.format(path, bit)
shutil.copy(source, dest)
with open(dest, 'a') as f:
f.write('SensorsOnly=1\n')
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():
"""Run HitmanPro in the background."""
extract_item('HitmanPro', silent=True)
cmd = [
global_vars['Tools']['HitmanPro'],
'/quiet', '/noinstall', '/noupload',
r'/log={LogDir}\Tools\HitmanPro.txt'.format(**global_vars)]
popen_program(cmd)
def run_process_killer():
"""Kill most running processes skipping those in the whitelist.txt."""
# borrowed from TronScript (reddit.com/r/TronScript)
# credit to /u/cuddlychops06
prev_dir = os.getcwd()
extract_item('ProcessKiller', silent=True)
os.chdir(r'{BinDir}\ProcessKiller'.format(**global_vars))
run_program(['ProcessKiller.exe', '/silent'], check=False)
os.chdir(prev_dir)
def run_rkill():
"""Run RKill and cleanup afterwards."""
extract_item('RKill', silent=True)
cmd = [
global_vars['Tools']['RKill'],
'-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')
# 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 = 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.")

View file

@ -1,395 +1,414 @@
# Wizard Kit: Functions - Disk
from functions.common import *
from functions import partition_uids
from settings.partition_uids import *
# Regex
REGEX_BAD_PARTITION = re.compile(r'(RAW|Unknown)', re.IGNORECASE)
REGEX_DISK_GPT = re.compile(
r'Disk ID: {[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+}',
re.IGNORECASE)
r'Disk ID: {[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+}',
re.IGNORECASE)
REGEX_DISK_MBR = re.compile(r'Disk ID: [A-Z0-9]+', re.IGNORECASE)
REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE)
def assign_volume_letters():
"""Assign a volume letter to all available volumes."""
remove_volume_letters()
"""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')
# Write script
script = []
for vol in get_volumes():
script.append('select volume {}'.format(vol['Number']))
script.append('assign')
# Run
run_diskpart(script)
# Run
run_diskpart(script)
def get_boot_mode():
"""Check if the boot mode was UEFI or legacy."""
boot_mode = 'Legacy'
try:
reg_key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE, r'System\CurrentControlSet\Control')
reg_value = winreg.QueryValueEx(reg_key, 'PEFirmwareType')[0]
if reg_value == 2:
boot_mode = 'UEFI'
except:
boot_mode = 'Unknown'
"""Check if the boot mode was UEFI or legacy."""
boot_mode = 'Legacy'
try:
reg_key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE, r'System\CurrentControlSet\Control')
reg_value = winreg.QueryValueEx(reg_key, 'PEFirmwareType')[0]
if reg_value == 2:
boot_mode = 'UEFI'
except:
boot_mode = 'Unknown'
return boot_mode
return boot_mode
def get_disk_details(disk):
"""Get disk details using DiskPart."""
details = {}
script = [
'select disk {}'.format(disk['Number']),
'detail disk']
"""Get disk details using DiskPart."""
details = {}
script = [
'select disk {}'.format(disk['Number']),
'detail disk']
# Run
try:
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
output = result.stdout.decode().strip()
# Remove empty lines
tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Set disk name
details['Name'] = tmp[4]
# Split each line on ':' skipping those without ':'
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})
# Run
try:
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
output = result.stdout.decode().strip()
# Remove empty lines
tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Set disk name
details['Name'] = tmp[4]
# Split each line on ':' skipping those without ':'
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
return details
def get_disks():
"""Get list of attached disks using DiskPart."""
disks = []
"""Get list of attached disks using DiskPart."""
disks = []
try:
# Run script
result = run_diskpart(['list disk'])
except subprocess.CalledProcessError:
pass
else:
# Append disk numbers
output = result.stdout.decode().strip()
for tmp in re.findall(r'Disk (\d+)\s+\w+\s+(\d+\s+\w+)', output):
num = tmp[0]
size = human_readable_size(tmp[1])
disks.append({'Number': num, 'Size': size})
try:
# Run script
result = run_diskpart(['list disk'])
except subprocess.CalledProcessError:
pass
else:
# Append disk numbers
output = result.stdout.decode().strip()
for tmp in re.findall(r'Disk (\d+)\s+\w+\s+(\d+\s+\w+)', output):
num = tmp[0]
size = human_readable_size(tmp[1])
disks.append({'Number': num, 'Size': size})
return disks
return disks
def get_partition_details(disk, partition):
"""Get partition details using DiskPart and fsutil."""
details = {}
script = [
'select disk {}'.format(disk['Number']),
'select partition {}'.format(partition['Number']),
'detail partition']
"""Get partition details using DiskPart and fsutil."""
details = {}
script = [
'select disk {}'.format(disk['Number']),
'select partition {}'.format(partition['Number']),
'detail partition']
# Diskpart details
# Diskpart details
try:
# Run script
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
# Get volume letter or RAW status
output = result.stdout.decode().strip()
tmp = re.search(r'Volume\s+\d+\s+(\w|RAW)\s+', output)
if tmp:
if tmp.group(1).upper() == 'RAW':
details['FileSystem'] = RAW
else:
details['Letter'] = tmp.group(1)
# Remove empty lines from output
tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Split each line on ':' skipping those without ':'
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.get(details.get('Type').upper(), {})
if guid:
details.update({
'Description': guid.get('Description', '')[:29],
'OS': guid.get('OS', 'Unknown')[:27]})
if 'Letter' in details:
# Disk usage
try:
# Run script
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
tmp = psutil.disk_usage('{}:\\'.format(details['Letter']))
except OSError as err:
details['FileSystem'] = 'Unknown'
details['Error'] = err.strerror
else:
# Get volume letter or RAW status
output = result.stdout.decode().strip()
tmp = re.search(r'Volume\s+\d+\s+(\w|RAW)\s+', output)
if tmp:
if tmp.group(1).upper() == 'RAW':
details['FileSystem'] = RAW
else:
details['Letter'] = tmp.group(1)
# Remove empty lines from output
tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Split each line on ':' skipping those without ':'
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})
details['Used Space'] = human_readable_size(tmp.used)
# 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]})
# fsutil details
cmd = [
'fsutil',
'fsinfo',
'volumeinfo',
'{}:'.format(details['Letter'])
]
try:
result = run_program(cmd)
except subprocess.CalledProcessError:
pass
else:
output = result.stdout.decode().strip()
# Remove empty lines from output
tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Add "Feature" lines
details['File System Features'] = [s.strip() for s in tmp
if ':' not in s]
# Split each line on ':' skipping those without ':'
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})
if 'Letter' in details:
# Disk usage
try:
tmp = psutil.disk_usage('{}:\\'.format(details['Letter']))
except OSError as err:
details['FileSystem'] = 'Unknown'
details['Error'] = err.strerror
else:
details['Used Space'] = human_readable_size(tmp.used)
# Set Volume Name
details['Name'] = details.get('Volume Name', '')
# fsutil details
cmd = [
'fsutil',
'fsinfo',
'volumeinfo',
'{}:'.format(details['Letter'])
]
try:
result = run_program(cmd)
except subprocess.CalledProcessError:
pass
else:
output = result.stdout.decode().strip()
# Remove empty lines from output
tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Add "Feature" lines
details['File System Features'] = [s.strip() for s in tmp
if ':' not in s]
# Split each line on ':' skipping those without ':'
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 FileSystem Type
if details.get('FileSystem', '') not in ['RAW', 'Unknown']:
details['FileSystem'] = details.get('File System Name', 'Unknown')
# Set Volume Name
details['Name'] = details.get('Volume Name', '')
return details
# 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):
"""Get list of partition using DiskPart."""
partitions = []
script = [
'select disk {}'.format(disk['Number']),
'list partition']
"""Get list of partition using DiskPart."""
partitions = []
script = [
'select disk {}'.format(disk['Number']),
'list partition']
try:
# Run script
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
# Append partition numbers
output = result.stdout.decode().strip()
regex = r'Partition\s+(\d+)\s+\w+\s+(\d+\s+\w+)\s+'
for tmp in re.findall(regex, output, re.IGNORECASE):
num = tmp[0]
size = human_readable_size(tmp[1])
partitions.append({'Number': num, 'Size': size})
try:
# Run script
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
# Append partition numbers
output = result.stdout.decode().strip()
regex = r'Partition\s+(\d+)\s+\w+\s+(\d+\s+\w+)\s+'
for tmp in re.findall(regex, output, re.IGNORECASE):
num = tmp[0]
size = human_readable_size(tmp[1])
partitions.append({'Number': num, 'Size': size})
return partitions
return partitions
def get_table_type(disk):
"""Get disk partition table type using DiskPart."""
part_type = 'Unknown'
script = [
'select disk {}'.format(disk['Number']),
'uniqueid disk']
"""Get disk partition table type using DiskPart."""
part_type = 'Unknown'
script = [
'select disk {}'.format(disk['Number']),
'uniqueid disk']
try:
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
output = result.stdout.decode().strip()
if REGEX_DISK_GPT.search(output):
part_type = 'GPT'
elif REGEX_DISK_MBR.search(output):
part_type = 'MBR'
elif REGEX_DISK_RAW.search(output):
part_type = 'RAW'
try:
result = run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
output = result.stdout.decode().strip()
if REGEX_DISK_GPT.search(output):
part_type = 'GPT'
elif REGEX_DISK_MBR.search(output):
part_type = 'MBR'
elif REGEX_DISK_RAW.search(output):
part_type = 'RAW'
return part_type
return part_type
def get_volumes():
"""Get list of volumes using DiskPart."""
vols = []
try:
result = run_diskpart(['list volume'])
except subprocess.CalledProcessError:
pass
else:
# Append volume numbers
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]})
"""Get list of volumes using DiskPart."""
vols = []
try:
result = run_diskpart(['list volume'])
except subprocess.CalledProcessError:
pass
else:
# Append volume numbers
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
return vols
def is_bad_partition(par):
"""Check if the partition is accessible."""
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
"""Check if the partition is accessible."""
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
def prep_disk_for_formatting(disk=None):
"""Gather details about the disk and its partitions."""
disk['Format Warnings'] = '\n'
width = len(str(len(disk['Partitions'])))
"""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.')
# Bail early
if disk is None:
raise Exception('Disk not provided.')
# Set boot method and partition table type
disk['Use GPT'] = True
if (get_boot_mode() == 'UEFI'):
if (not ask("Setup Windows to use UEFI booting?")):
disk['Use GPT'] = False
# Set boot method and partition table type
disk['Use GPT'] = True
if (get_boot_mode() == 'UEFI'):
if (not ask("Setup Windows to use UEFI booting?")):
disk['Use GPT'] = False
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'
for partition in disk['Partitions']:
display = '{size} {fs}'.format(
num = partition['Number'],
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(
display = display,
q = '"' if partition['Name'] != '' else '',
name = partition['Name'],
desc = partition['Description'],
os = partition['OS'])
else:
if (ask("Setup Windows to use BIOS/Legacy booting?")):
disk['Use GPT'] = False
# List space used instead of partition description & OS type
display += ' (Used: {used})\t{q}{name}{q}'.format(
used = partition['Used Space'],
q = '"' if partition['Name'] != '' else '',
name = partition['Name'])
# For all partitions
partition['Display String'] = display
# Set Display and Warning Strings
if len(disk['Partitions']) == 0:
disk['Format Warnings'] += 'No partitions found\n'
for partition in disk['Partitions']:
display = '{size} {fs}'.format(
num = partition['Number'],
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(
display = display,
q = '"' if partition['Name'] != '' else '',
name = partition['Name'],
desc = partition['Description'],
os = partition['OS'])
else:
# List space used instead of partition description & OS type
display += ' (Used: {used})\t{q}{name}{q}'.format(
used = partition['Used Space'],
q = '"' if partition['Name'] != '' else '',
name = partition['Name'])
# For all partitions
partition['Display String'] = display
def reassign_volume_letter(letter, new_letter='I'):
"""Assign a new letter to a volume using DiskPart."""
if not letter:
# Ignore
return None
script = [
'select volume {}'.format(letter),
'remove noerr',
'assign letter={}'.format(new_letter)]
try:
run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
return new_letter
"""Assign a new letter to a volume using DiskPart."""
if not letter:
# Ignore
return None
script = [
'select volume {}'.format(letter),
'remove noerr',
'assign letter={}'.format(new_letter)]
try:
run_diskpart(script)
except subprocess.CalledProcessError:
pass
else:
return new_letter
def remove_volume_letters(keep=None):
"""Remove all assigned volume letters using DiskPart."""
if not keep:
keep = ''
"""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')
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)
except subprocess.CalledProcessError:
pass
# Run script
try:
run_diskpart(script)
except subprocess.CalledProcessError:
pass
def run_diskpart(script):
"""Run DiskPart script."""
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
"""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))
# 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(
global_vars['Env']['SYSTEMDRIVE']),
'/s', tempfile]
result = run_program(cmd)
sleep(2)
return result
# Run script
cmd = [
r'{}\Windows\System32\diskpart.exe'.format(
global_vars['Env']['SYSTEMDRIVE']),
'/s', tempfile]
result = run_program(cmd)
sleep(2)
return result
def scan_disks():
"""Get details about the attached disks"""
disks = get_disks()
"""Get details about the attached disks"""
disks = get_disks()
# Get disk details
for disk in disks:
# Get partition style
disk['Table'] = get_table_type(disk)
# Get disk details
for disk in disks:
# Get partition style
disk['Table'] = get_table_type(disk)
# Get disk name/model and physical details
disk.update(get_disk_details(disk))
# Get disk name/model and physical details
disk.update(get_disk_details(disk))
# Get partition info for disk
disk['Partitions'] = get_partitions(disk)
# 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))
for partition in disk['Partitions']:
# Get partition details
partition.update(get_partition_details(disk, partition))
# Done
return disks
# Done
return disks
def select_disk(title='Which disk?', disks=[]):
"""Select a disk from the attached disks"""
# Build menu
disk_options = []
for disk in disks:
display_name = '{}\t[{}] ({}) {}'.format(
disk.get('Size', ''),
disk.get('Table', ''),
disk.get('Type', ''),
disk.get('Name', 'Unknown'),
)
pwidth=len(str(len(disk['Partitions'])))
for partition in disk['Partitions']:
# Main text
p_name = 'Partition {num:>{width}}: {size} ({fs})'.format(
num = partition['Number'],
width = pwidth,
size = partition['Size'],
fs = partition['FileSystem'])
if partition['Name']:
p_name += '\t"{}"'.format(partition['Name'])
"""Select a disk from the attached disks"""
# Build menu
disk_options = []
for disk in disks:
display_name = '{}\t[{}] ({}) {}'.format(
disk.get('Size', ''),
disk.get('Table', ''),
disk.get('Type', ''),
disk.get('Name', 'Unknown'),
)
pwidth=len(str(len(disk['Partitions'])))
for partition in disk['Partitions']:
# Main text
p_name = 'Partition {num:>{width}}: {size} ({fs})'.format(
num = partition['Number'],
width = pwidth,
size = partition['Size'],
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)
# 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(
COLORS['YELLOW'], COLORS['CLEAR'])
display_name += '\n\t\t\t{}'.format(p_name)
if not disk['Partitions']:
display_name += '\n\t\t\t{}No partitions found.{}'.format(
COLORS['YELLOW'], COLORS['CLEAR'])
disk_options.append({'Name': display_name, 'Disk': disk})
actions = [
{'Name': 'Main Menu', 'Letter': 'M'},
]
disk_options.append({'Name': display_name, 'Disk': disk})
actions = [
{'Name': 'Main Menu', 'Letter': 'M'},
]
# Menu loop
selection = menu_select(
title = title,
main_entries = disk_options,
action_entries = actions)
# Menu loop
selection = menu_select(
title = title,
main_entries = disk_options,
action_entries = actions)
if (selection.isnumeric()):
return disk_options[int(selection)-1]['Disk']
elif (selection == 'M'):
raise GenericAbort
if (selection.isnumeric()):
return disk_options[int(selection)-1]['Disk']
elif (selection == 'M'):
raise GenericAbort
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

File diff suppressed because it is too large Load diff

View file

@ -1,520 +1,500 @@
# Wizard Kit: Functions - Information
from borrowed import knownpaths
from operator import itemgetter
from functions.common import *
from functions.activation import *
from operator import itemgetter
from settings.info import *
# Regex
REGEX_OFFICE = re.compile(
r'(Microsoft (Office\s+'
r'(365|Enterprise|Home|Pro(\s|fessional)'
r'|Single|Small|Standard|Starter|Ultimate|system)'
r'|Works[-\s\d]+\d)'
r'|(Libre|Open|Star)\s*Office'
r'|WordPerfect|Gnumeric|Abiword)',
re.IGNORECASE)
# STATIC VARIABLES
REG_PROFILE_LIST = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
REG_SHELL_FOLDERS = r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
TMP_HIVE_PATH = 'TEMP_HIVE_MOUNT'
EXTRA_FOLDERS = [
'Dropbox',
'Google Drive',
'OneDrive',
'SkyDrive',
]
SHELL_FOLDERS = {
#GUIDs from: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
'Desktop': (
'{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}',
),
'Documents': (
'Personal',
'{FDD39AD0-238F-46AF-ADB4-6C85480369C7}',
),
'Downloads': (
'{374DE290-123F-4565-9164-39C4925E467B}',
),
'Favorites': (
'{1777F761-68AD-4D8A-87BD-30B759FA33DD}',
),
'Music': (
'My Music',
'{4BD8D571-6D19-48D3-BE97-422220080E43}',
),
'Pictures': (
'My Pictures',
'{33E28130-4E1E-4676-835A-98395C3BC3BB}',
),
'Videos': (
'My Video',
'{18989B1D-99B5-455B-841C-AB7C74E4DDFC}',
),
}
def backup_file_list():
"""Export current file listing for the system."""
extract_item('Everything', silent=True)
cmd = [
global_vars['Tools']['Everything'],
'-nodb',
'-create-filelist',
r'{LogDir}\File List.txt'.format(**global_vars),
global_vars['Env']['SYSTEMDRIVE']]
run_program(cmd)
"""Export current file listing for the system."""
extract_item('Everything', silent=True)
cmd = [
global_vars['Tools']['Everything'],
'-nodb',
'-create-filelist',
r'{LogDir}\File List.txt'.format(**global_vars),
global_vars['Env']['SYSTEMDRIVE']]
run_program(cmd)
def backup_power_plans():
"""Export current power plans."""
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)]
for p in 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\{Date}\{name}.pow'.format(
name=name, **global_vars)
if not os.path.exists(out):
cmd = ['powercfg', '-export', out, guid]
run_program(cmd, check=False)
"""Export current power plans."""
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)]
for p in 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\{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(overwrite=False):
"""Backup registry including user hives."""
extract_item('erunt', silent=True)
cmd = [
global_vars['Tools']['ERUNT'],
r'{BackupDir}\Registry\{Date}'.format(**global_vars),
'sysreg',
'curuser',
'otherusers',
'/noprogresswindow']
if overwrite:
cmd.append('/noconfirmdelete')
run_program(cmd)
"""Backup registry including user hives."""
extract_item('erunt', silent=True)
cmd = [
global_vars['Tools']['ERUNT'],
r'{BackupDir}\Registry\{Date}'.format(**global_vars),
'sysreg',
'curuser',
'otherusers',
'/noprogresswindow']
if overwrite:
cmd.append('/noconfirmdelete')
run_program(cmd)
def get_folder_size(path):
"""Get (human-readable) size of folder passed, returns str."""
size = 'Unknown'
cmd = [global_vars['Tools']['Du'], '-c', '-nobanner', '-q', path]
"""Get (human-readable) size of folder passed, returns str."""
size = 'Unknown'
cmd = [global_vars['Tools']['Du'], '-c', '-nobanner', '-q', path]
try:
out = run_program(cmd)
except FileNotFoundError:
# Failed to find folder
pass
except subprocess.CalledProcessError:
# Failed to get folder size
pass
else:
try:
out = run_program(cmd)
except FileNotFoundError:
# Failed to find folder
pass
except subprocess.CalledProcessError:
# Failed to get folder size
pass
size = out.stdout.decode().split(',')[-2]
except IndexError:
# Failed to parse csv data
pass
else:
try:
size = out.stdout.decode().split(',')[-2]
except IndexError:
# Failed to parse csv data
pass
else:
size = human_readable_size(size)
return size
size = human_readable_size(size)
return size
def get_installed_antivirus():
"""Get list of installed Antivirus programs."""
programs = []
"""Get list of installed Antivirus programs."""
programs = []
cmd = ['WMIC', r'/namespace:\\root\SecurityCenter2',
'path', 'AntivirusProduct',
'get', 'displayName', '/value']
out = run_program(cmd)
out = out.stdout.decode().strip()
products = out.splitlines()
products = [p.split('=')[1] for p in products if p]
for prod in sorted(products):
# Get product state and check if it's enabled
# credit: https://jdhitsolutions.com/blog/powershell/5187/get-antivirus-product-status-with-powershell/
cmd = ['WMIC', r'/namespace:\\root\SecurityCenter2',
'path', 'AntivirusProduct',
'get', 'displayName', '/value']
'path', 'AntivirusProduct',
'where', 'displayName="{}"'.format(prod),
'get', 'productState', '/value']
out = run_program(cmd)
out = out.stdout.decode().strip()
products = out.splitlines()
products = [p.split('=')[1] for p in products if p]
for prod in sorted(products):
# Get product state and check if it's enabled
# credit: https://jdhitsolutions.com/blog/powershell/5187/get-antivirus-product-status-with-powershell/
cmd = ['WMIC', r'/namespace:\\root\SecurityCenter2',
'path', 'AntivirusProduct',
'where', 'displayName="{}"'.format(prod),
'get', 'productState', '/value']
out = run_program(cmd)
out = out.stdout.decode().strip()
state = out.split('=')[1]
state = hex(int(state))
if str(state)[3:5] != '10':
programs.append('[Disabled] {}'.format(prod))
else:
programs.append(prod)
state = out.split('=')[1]
state = hex(int(state))
if str(state)[3:5] not in ['10', '11']:
programs.append('[Disabled] {}'.format(prod))
else:
programs.append(prod)
if len(programs) == 0:
programs = ['No programs found']
return programs
if len(programs) == 0:
programs = ['No programs found']
return programs
def get_installed_office():
"""Get list of installed Office programs."""
programs = []
log_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format(
**global_vars)
with open (log_file, 'r') as f:
for line in sorted(f.readlines()):
if REGEX_OFFICE.search(line):
programs.append(line[4:82].strip())
"""Get list of installed Office programs."""
programs = []
log_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format(
**global_vars)
with open (log_file, 'r') as f:
for line in sorted(f.readlines()):
if REGEX_OFFICE.search(line):
programs.append(line[4:82].strip())
if len(programs) == 0:
programs = ['No programs found']
return programs
if len(programs) == 0:
programs = ['No programs found']
return programs
def get_shell_path(folder, user='current'):
"""Get shell path using SHGetKnownFolderPath via knownpaths, returns str.
"""Get shell path using knownpaths, returns str.
NOTE: Only works for the current user.
Code based on https://gist.github.com/mkropat/7550097
"""
path = None
folderid = None
if user.lower() == 'public':
user = 'common'
NOTE: Only works for the current user.
Code based on https://gist.github.com/mkropat/7550097
"""
path = None
folderid = None
if user.lower() == 'public':
user = 'common'
try:
folderid = getattr(knownpaths.FOLDERID, folder)
except AttributeError:
# Unknown folder ID, ignore and return None
pass
if folderid:
try:
folderid = getattr(knownpaths.FOLDERID, folder)
except AttributeError:
# Unknown folder ID, ignore and return None
pass
path = knownpaths.get_path(
folderid, getattr(knownpaths.UserHandle, user))
except PathNotFoundError:
# Folder not found, 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
return path
def get_user_data_paths(user):
"""Get user data paths for provided user, returns dict."""
hive_path = user['SID']
paths = {
'Profile': {
'Path': None,
},
'Shell Folders': {},
'Extra Folders': {},
}
unload_hive = False
"""Get user data paths for provided user, returns dict."""
hive_path = user['SID']
paths = {
'Profile': {
'Path': None,
},
'Shell Folders': {},
'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')
paths['Shell Folders'] = {f: {'Path': get_shell_path(f)}
for f in SHELL_FOLDERS.keys()}
else:
# We have to use the NTUSER.dat hives which isn't recommended by MS
try:
key_path = r'{}\{}'.format(REG_PROFILE_LIST, user['SID'])
with winreg.OpenKey(HKLM, key_path) as key:
paths['Profile']['Path'] = winreg.QueryValueEx(
key, 'ProfileImagePath')[0]
except Exception:
# Profile path not found, leaving as None.
pass
if user['Name'] == global_vars['Env']['USERNAME']:
# We can use SHGetKnownFolderPath for the current user
paths['Profile']['Path'] = get_shell_path('Profile')
paths['Shell Folders'] = {f: {'Path': get_shell_path(f)}
for f in SHELL_FOLDERS.keys()}
else:
# We have to use the NTUSER.dat hives which isn't recommended by MS
try:
key_path = r'{}\{}'.format(REG_PROFILE_LIST, user['SID'])
with winreg.OpenKey(HKLM, key_path) as key:
paths['Profile']['Path'] = winreg.QueryValueEx(
key, 'ProfileImagePath')[0]
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
# Also setting unload_hive so it will be unloaded later.
hive_path = TMP_HIVE_PATH
cmd = ['reg', 'load', r'HKU\{}'.format(TMP_HIVE_PATH),
r'{}\NTUSER.DAT'.format(paths['Profile']['Path'])]
unload_hive = True
# Shell folders (Prep)
if not reg_path_exists(HKU, hive_path) and paths['Profile']['Path']:
# User not logged-in, loading hive
# Also setting unload_hive so it will be unloaded later.
hive_path = TMP_HIVE_PATH
cmd = ['reg', 'load', r'HKU\{}'.format(TMP_HIVE_PATH),
r'{}\NTUSER.DAT'.format(paths['Profile']['Path'])]
unload_hive = True
try:
run_program(cmd)
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)
and reg_path_exists(HKU, shell_folders)):
with winreg.OpenKey(HKU, shell_folders) as key:
for folder, values in SHELL_FOLDERS.items():
for value in values:
try:
run_program(cmd)
except subprocess.CalledProcessError:
# Failed to load user hive
pass
path = winreg.QueryValueEx(key, value)[0]
except FileNotFoundError:
# Skip missing values
pass
else:
paths['Shell Folders'][folder] = {'Path': path}
# Stop checking values for this folder
break
# Shell folders
shell_folders = r'{}\{}'.format(hive_path, REG_SHELL_FOLDERS)
if (reg_path_exists(HKU, hive_path)
and reg_path_exists(HKU, shell_folders)):
with winreg.OpenKey(HKU, shell_folders) as key:
for folder, values in SHELL_FOLDERS.items():
for value in values:
try:
path = winreg.QueryValueEx(key, value)[0]
except FileNotFoundError:
# Skip missing values
pass
else:
paths['Shell Folders'][folder] = {'Path': path}
# Stop checking values for this folder
break
# Shell folder (extra check)
if paths['Profile']['Path']:
for folder in SHELL_FOLDERS.keys():
folder_path = r'{Path}\{folder}'.format(
folder=folder, **paths['Profile'])
if (folder not in paths['Shell Folders']
and os.path.exists(folder_path)):
paths['Shell Folders'][folder] = {'Path': folder_path}
# Extra folders
# Shell folder (extra check)
if paths['Profile']['Path']:
for folder in EXTRA_FOLDERS:
folder_path = r'{Path}\{folder}'.format(
folder=folder, **paths['Profile'])
if os.path.exists(folder_path):
paths['Extra Folders'][folder] = {'Path': folder_path}
for folder in SHELL_FOLDERS.keys():
folder_path = r'{Path}\{folder}'.format(
folder=folder, **paths['Profile'])
if (folder not in paths['Shell Folders']
and os.path.exists(folder_path)):
paths['Shell 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)
# Extra folders
if paths['Profile']['Path']:
for folder in EXTRA_FOLDERS:
folder_path = r'{Path}\{folder}'.format(
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
# Done
return paths
def get_user_folder_sizes(users):
"""Update list(users) to include folder paths and sizes."""
extract_item('du', filter='du*', silent=True)
# Configure Du
winreg.CreateKey(HKCU, r'Software\Sysinternals\Du')
with winreg.OpenKey(HKCU,
r'Software\Sysinternals\Du', access=winreg.KEY_WRITE) as key:
winreg.SetValueEx(key, 'EulaAccepted', 0, winreg.REG_DWORD, 1)
"""Update list(users) to include folder paths and sizes."""
extract_item('du', filter='du*', silent=True)
# Configure Du
winreg.CreateKey(HKCU, r'Software\Sysinternals\Du')
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']:
u['Profile']['Size'] = get_folder_size(u['Profile']['Path'])
for folder in u['Shell Folders'].keys():
u['Shell Folders'][folder]['Size'] = get_folder_size(
u['Shell Folders'][folder]['Path'])
for folder in u['Extra Folders'].keys():
u['Extra Folders'][folder]['Size'] = get_folder_size(
u['Extra Folders'][folder]['Path'])
for u in users:
u.update(get_user_data_paths(u))
if u['Profile']['Path']:
u['Profile']['Size'] = get_folder_size(u['Profile']['Path'])
for folder in u['Shell Folders'].keys():
u['Shell Folders'][folder]['Size'] = get_folder_size(
u['Shell Folders'][folder]['Path'])
for folder in u['Extra Folders'].keys():
u['Extra Folders'][folder]['Size'] = get_folder_size(
u['Extra Folders'][folder]['Path'])
def get_user_list():
"""Get user list via WMIC, returns list of dicts."""
users = []
"""Get user list via WMIC, returns list of dicts."""
users = []
# Get user info from WMI
cmd = ['wmic', 'useraccount', 'get', '/format:csv']
try:
out = run_program(cmd)
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:]:
# Create dict using 1st line (keys)
e = dict(zip(keys, e))
# Set Active status via 'Disabled' TRUE/FALSE str
e['Active'] = bool(e['Disabled'].upper() == 'FALSE')
# 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
# Get user info from WMI
cmd = ['wmic', 'useraccount', 'get', '/format:csv']
try:
out = run_program(cmd)
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:]:
# Create dict using 1st line (keys)
e = dict(zip(keys, e))
# Set Active status via 'Disabled' TRUE/FALSE str
e['Active'] = bool(e['Disabled'].upper() == 'FALSE')
# 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
def reg_path_exists(hive, path):
"""Test if specified path exists, returns bool."""
try:
winreg.QueryValue(hive, path)
except FileNotFoundError:
return False
else:
return True
"""Test if specified path exists, returns bool."""
try:
winreg.QueryValue(hive, path)
except FileNotFoundError:
return False
else:
return True
def run_aida64():
"""Run AIDA64 to save system reports."""
extract_item('AIDA64', silent=True)
# All system info
config = r'{BinDir}\AIDA64\full.rpf'.format(**global_vars)
report_file = r'{LogDir}\System Information (AIDA64).html'.format(
**global_vars)
if not os.path.exists(report_file):
cmd = [
global_vars['Tools']['AIDA64'],
'/R', report_file,
'/CUSTOM', config,
'/HTML', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
"""Run AIDA64 to save system reports."""
extract_item('AIDA64', silent=True)
# All system info
config = r'{BinDir}\AIDA64\full.rpf'.format(**global_vars)
report_file = r'{LogDir}\System Information (AIDA64).html'.format(
**global_vars)
if not os.path.exists(report_file):
cmd = [
global_vars['Tools']['AIDA64'],
'/R', report_file,
'/CUSTOM', config,
'/HTML', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
# Installed Programs
config = r'{BinDir}\AIDA64\installed_programs.rpf'.format(**global_vars)
report_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format(
**global_vars)
if not os.path.exists(report_file):
cmd = [
global_vars['Tools']['AIDA64'],
'/R', report_file,
'/CUSTOM', config,
'/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
# Installed Programs
config = r'{BinDir}\AIDA64\installed_programs.rpf'.format(**global_vars)
report_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format(
**global_vars)
if not os.path.exists(report_file):
cmd = [
global_vars['Tools']['AIDA64'],
'/R', report_file,
'/CUSTOM', config,
'/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
# Product Keys
config = r'{BinDir}\AIDA64\licenses.rpf'.format(**global_vars)
report_file = r'{LogDir}\Product Keys (AIDA64).txt'.format(**global_vars)
if not os.path.exists(report_file):
cmd = [
global_vars['Tools']['AIDA64'],
'/R', report_file,
'/CUSTOM', config,
'/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
# Product Keys
config = r'{BinDir}\AIDA64\licenses.rpf'.format(**global_vars)
report_file = r'{LogDir}\Product Keys (AIDA64).txt'.format(**global_vars)
if not os.path.exists(report_file):
cmd = [
global_vars['Tools']['AIDA64'],
'/R', report_file,
'/CUSTOM', config,
'/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False)
def run_bleachbit(cleaners=None, preview=True):
"""Run BleachBit preview and save log.
"""Run BleachBit preview and save log.
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)
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
# 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)
# 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 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')
# 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('/', ' ')),
end='', flush=True, timestamp=False)
try:
usage = psutil.disk_usage(disk.device)
display_string = '{percent:>5.2f}% Free ({free} / {total})'.format(
percent = 100 - usage.percent,
free = human_readable_size(usage.free, 2),
total = human_readable_size(usage.total, 2))
if usage.percent > 85:
print_error(display_string, timestamp=False)
elif usage.percent > 75:
print_warning(display_string, timestamp=False)
else:
print_standard(display_string, timestamp=False)
except Exception:
print_warning('Unknown', timestamp=False)
"""Show free and used space for a specified disk."""
print_standard('{:5}'.format(disk.device.replace('/', ' ')),
end='', flush=True, timestamp=False)
try:
usage = psutil.disk_usage(disk.device)
display_string = '{percent:>5.2f}% Free ({free} / {total})'.format(
percent = 100 - usage.percent,
free = human_readable_size(usage.free, 2),
total = human_readable_size(usage.total, 2))
if usage.percent > 85:
print_error(display_string, timestamp=False)
elif usage.percent > 75:
print_warning(display_string, timestamp=False)
else:
print_standard(display_string, timestamp=False)
except Exception:
print_warning('Unknown', timestamp=False)
def show_free_space(indent=8, width=32):
"""Show free space info for all fixed disks."""
message = 'Free Space:'
for disk in psutil.disk_partitions():
try:
if 'fixed' in disk.opts:
try_and_print(message=message, function=show_disk_usage,
ns='Unknown', silent_function=False,
indent=indent, width=width, disk=disk)
message = ''
except Exception:
pass
"""Show free space info for all fixed disks."""
message = 'Free Space:'
for disk in psutil.disk_partitions():
try:
if 'fixed' in disk.opts:
try_and_print(message=message, function=show_disk_usage,
ns='Unknown', silent_function=False,
indent=indent, width=width, disk=disk)
message = ''
except Exception:
pass
def show_installed_ram():
"""Show installed RAM."""
mem = psutil.virtual_memory()
if mem.total > 5905580032:
# > 5.5 Gb so 6Gb or greater
print_standard(human_readable_size(mem.total).strip(), timestamp=False)
elif mem.total > 3758096384:
# > 3.5 Gb so 4Gb or greater
print_warning(human_readable_size(mem.total).strip(), timestamp=False)
else:
print_error(human_readable_size(mem.total).strip(), timestamp=False)
"""Show installed RAM."""
mem = psutil.virtual_memory()
if mem.total > 5905580032:
# > 5.5 Gb so 6Gb or greater
print_standard(human_readable_size(mem.total).strip(), timestamp=False)
elif mem.total > 3758096384:
# > 3.5 Gb so 4Gb or greater
print_warning(human_readable_size(mem.total).strip(), timestamp=False)
else:
print_error(human_readable_size(mem.total).strip(), timestamp=False)
def show_os_activation():
"""Show OS activation info."""
act_str = get_activation_string()
if windows_is_activated():
print_standard(act_str, timestamp=False)
elif re.search(r'unavailable', act_str, re.IGNORECASE):
print_warning(act_str, timestamp=False)
else:
print_error(act_str, timestamp=False)
"""Show OS activation info."""
act_str = get_activation_string()
if windows_is_activated():
print_standard(act_str, timestamp=False)
elif re.search(r'unavailable', act_str, re.IGNORECASE):
print_warning(act_str, timestamp=False)
else:
print_error(act_str, timestamp=False)
def show_os_name():
"""Show extended OS name (including warnings)."""
os_name = global_vars['OS']['DisplayName']
if global_vars['OS']['Arch'] == 32:
# Show all 32-bit installs as an error message
print_error(os_name, timestamp=False)
"""Show extended OS name (including warnings)."""
os_name = global_vars['OS']['DisplayName']
if global_vars['OS']['Arch'] == 32:
# Show all 32-bit installs as an error message
print_error(os_name, timestamp=False)
else:
if re.search(
r'(preview build|unrecognized|unsupported)',
os_name,
re.IGNORECASE):
print_error(os_name, timestamp=False)
elif re.search(r'outdated', os_name, re.IGNORECASE):
print_warning(os_name, timestamp=False)
else:
if re.search(r'(preview build|unrecognized|unsupported)', os_name, re.IGNORECASE):
print_error(os_name, timestamp=False)
elif re.search(r'outdated', os_name, re.IGNORECASE):
print_warning(os_name, timestamp=False)
else:
print_standard(os_name, timestamp=False)
print_standard(os_name, timestamp=False)
def show_temp_files_size():
"""Show total size of temp files identified by BleachBit."""
size = None
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())
size = re.sub(r'(\w)iB$', r' \1b', size)
if size is None:
print_warning(size, timestamp=False)
else:
print_standard(size, timestamp=False)
"""Show total size of temp files identified by BleachBit."""
size_str = None
total = 0
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())
size = re.sub(r'(\w)iB$', r' \1b', size)
total += convert_to_bytes(size)
size_str = human_readable_size(total, decimals=1)
if size_str is None:
print_warning('UNKNOWN', timestamp=False)
else:
print_standard(size_str, timestamp=False)
def show_user_data_summary(indent=8, width=32):
"""Print user data folder sizes for all users."""
users = get_user_list()
users = [u for u in users if u['Active']]
get_user_folder_sizes(users)
for user in users:
if ('Size' not in user['Profile']
and not any(user['Shell Folders'])
and not any(user['Extra Folders'])):
# Skip empty users
continue
print_success('{indent}User: {user}'.format(
indent = ' '*int(indent/2),
user = user['Name']))
for section in ['Profile', None, 'Shell Folders', 'Extra Folders']:
folders = []
if section is None:
# Divider
print_standard('{}{}'.format(' '*indent, '-'*(width+6)))
elif section == 'Profile':
folders = {'Profile': user['Profile']}
else:
folders = user[section]
for folder in folders:
print_standard(
'{indent}{folder:<{width}}{size:>6} ({path})'.format(
indent = ' ' * indent,
width = width,
folder = folder,
size = folders[folder].get('Size', 'Unknown'),
path = folders[folder].get('Path', 'Unknown')))
"""Print user data folder sizes for all users."""
users = get_user_list()
users = [u for u in users if u['Active']]
get_user_folder_sizes(users)
for user in users:
if ('Size' not in user['Profile']
and not any(user['Shell Folders'])
and not any(user['Extra Folders'])):
# Skip empty users
continue
print_success('{indent}User: {user}'.format(
indent = ' '*int(indent/2),
user = user['Name']))
for section in ['Profile', None, 'Shell Folders', 'Extra Folders']:
folders = []
if section is None:
# Divider
print_standard('{}{}'.format(' '*indent, '-'*(width+6)))
elif section == 'Profile':
folders = {'Profile': user['Profile']}
else:
folders = user[section]
for folder in folders:
print_standard(
'{indent}{folder:<{width}}{size:>6} ({path})'.format(
indent = ' ' * indent,
width = width,
folder = folder,
size = folders[folder].get('Size', 'Unknown'),
path = folders[folder].get('Path', 'Unknown')))
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,32 @@
# Wizard Kit: Functions - JSON
import json
from functions.common import *
def get_json_from_command(cmd, check=True, ignore_errors=True):
"""Capture JSON content from cmd output, returns dict.
If the data can't be decoded then either an exception is raised
or an empty dict is returned depending on ignore_errors.
"""
errors = 'strict'
json_data = {}
if ignore_errors:
errors = 'ignore'
try:
result = run_program(cmd, check=check, encoding='utf-8', errors=errors)
json_data = json.loads(result.stdout)
except (subprocess.CalledProcessError, json.decoder.JSONDecodeError):
if not ignore_errors:
raise
return json_data
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,72 +1,53 @@
#!/bin/python3
#
## Wizard Kit: Functions - Network
# Wizard Kit: Functions - Network
import os
import shutil
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.common import *
# REGEX
REGEX_VALID_IP = re.compile(
r'(10.\d+.\d+.\d+'
r'|172.(1[6-9]|2\d|3[0-1])'
r'|192.168.\d+.\d+)',
re.IGNORECASE)
r'(10.\d+.\d+.\d+'
r'|172.(1[6-9]|2\d|3[0-1])'
r'|192.168.\d+.\d+)',
re.IGNORECASE)
def connect_to_network():
"""Connect to network if not already connected."""
net_ifs = psutil.net_if_addrs()
net_ifs = [i[:2] for i in net_ifs.keys()]
# Bail if currently connected
if is_connected():
return
# WiFi
if 'wl' in net_ifs:
cmd = [
'nmcli', 'dev', 'wifi',
'connect', WIFI_SSID,
'password', WIFI_PASSWORD]
try_and_print(
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()
for dev in devs.values():
for family in dev:
if REGEX_VALID_IP.search(family.address):
# Valid IP found
return True
# Else
return False
"""Check for a valid private IP."""
devs = psutil.net_if_addrs()
for dev in devs.values():
for family in dev:
if REGEX_VALID_IP.search(family.address):
# Valid IP found
return True
# Else
return False
def show_valid_addresses():
"""Show all valid private IP addresses assigned to the system."""
devs = psutil.net_if_addrs()
for dev, families in sorted(devs.items()):
for family in families:
if REGEX_VALID_IP.search(family.address):
# Valid IP found
show_data(message=dev, data=family.address)
"""Show all valid private IP addresses assigned to the system."""
devs = psutil.net_if_addrs()
for dev, families in sorted(devs.items()):
for family in families:
if REGEX_VALID_IP.search(family.address):
# Valid IP found
show_data(message=dev, data=family.address)
def speedtest():
"""Run a network speedtest using speedtest-cli."""
result = run_program(['speedtest-cli', '--simple'])
output = [line.strip() for line in result.stdout.decode().splitlines()
if line.strip()]
output = [line.split() for line in output]
output = [(a, float(b), c) for a, b, c in output]
return ['{:10}{:6.2f} {}'.format(*line) for line in output]
"""Run a network speedtest using speedtest-cli."""
result = run_program(['speedtest-cli', '--simple'])
output = [line.strip() for line in result.stdout.decode().splitlines()
if line.strip()]
output = [line.split() for line in output]
output = [(a, float(b), c) for a, b, c in output]
return ['{:10}{:6.2f} {}'.format(*line) for line in output]
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,326 +0,0 @@
# Wizard Kit: Functions - PARTITION UIDs
# sources: https://en.wikipedia.org/wiki/GUID_Partition_Table
# https://en.wikipedia.org/wiki/Partition_type
# NOTE: Info has been trimmed for brevity. As such, there may be some inaccuracy.
PARTITION_UIDS = {
'00': {'OS': 'All','Description': 'Empty partition entry'},
'01': {'OS': 'DOS','Description': 'FAT12 as primary partition'},
'02': {'OS': 'XENIX','Description': 'XENIX root'},
'03': {'OS': 'XENIX','Description': 'XENIX usr'},
'04': {'OS': 'DOS','Description': 'FAT16 with less than 32 MB'},
'05': {'OS': 'DOS / SpeedStor','Description': 'Extended partition'},
'06': {'OS': 'DOS1+','Description': 'FAT16B [over 65K sectors]'},
'07': {'OS': 'Windows / OS/2 / QNX 2','Description': 'NTFS/exFAT/HPFS/IFS/QNX'},
'08': {'OS': 'CBM / DOS / OS/2 / AIX /QNX','Description': 'FAT12-16/AIX/QNY/SplitDrive'},
'09': {'OS': 'AIX / QNX / Coherent / OS-9','Description': 'AIX/QNZ/Coherent/RBF'},
'0A': {'OS': 'OS/2 / Coherent','Description': 'Boot Manager / Swap'},
'0B': {'OS': 'DOS','Description': 'FAT32 with CHS addressing'},
'0C': {'OS': 'DOS','Description': 'FAT32 with LBA'},
'0D': {'OS': 'Silicon Safe','Description': 'Reserved'},
'0E': {'OS': 'DOS','Description': 'FAT16B with LBA'},
'0F': {'OS': 'DOS','Description': 'Extended partition with LBA'},
'10': {'OS': 'OPUS','Description': 'Unknown'},
'11': {'OS': 'Leading Edge MS-DOS / OS/2','Description': 'FAT12/FAT16'},
'12': {'OS': 'Compaq Contura','Description': 'conf/diag/hiber/rescue/serv'},
'14': {'OS': 'AST DOS / OS/2 / MaverickOS','Description': 'FAT12/FAT16/Omega'},
'15': {'OS': 'OS/2 / Maverick OS','Description': 'Hidden extended / Swap'},
'16': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT16B'},
'17': {'OS': 'OS/2 Boot Manager','Description': 'Hidden IFS/HPFS/NTFS/exFAT'},
'18': {'OS': 'AST Windows','Description': '0-Volt Suspend/SmartSleep'},
'19': {'OS': 'Willowtech Photon coS','Description': 'Willowtech Photon coS'},
'1B': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT32'},
'1C': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT32 with LBA'},
'1E': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT16 with LBA'},
'1F': {'OS': 'OS/2 Boot Manager','Description': 'Hidden extended with LBA'},
'20': {'OS': 'Windows Mobile','Description': 'update XIP/Willowsoft OFS1'},
'21': {'OS': 'Oxygen','Description': 'SpeedStor / FSo2'},
'22': {'OS': 'Oxygen','Description': 'Oxygen Extended Partition'},
'23': {'OS': 'Windows Mobile','Description': 'Reserved / boot XIP'},
'24': {'OS': 'NEC MS-DOS0','Description': 'Logical FAT12 or FAT16'},
'25': {'OS': 'Windows Mobile','Description': 'IMGFS[citation needed]'},
'26': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'27': {'OS': 'Win/PQserv/MirOS/RooterBOOT','Description': 'WinRE/Rescue/MirOS/RooterBOOT'},
'2A': {'OS': 'AtheOS','Description': 'AthFS/AFS/Reserved'},
'2B': {'OS': 'SyllableOS','Description': 'SyllableSecure (SylStor)'},
'31': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'32': {'OS': 'NOS','Description': 'Unknown'},
'33': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'34': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'35': {'OS': 'OS/2 Server /eComStation','Description': 'JFS'},
'36': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'38': {'OS': 'THEOS','Description': 'THEOS version 3.2, 2 GB'},
'39': {'OS': 'Plan 9 / THEOS','Description': 'Plan 9 edition 3 / THEOS v4'},
'3A': {'OS': 'THEOS','Description': 'THEOS v4, 4 GB'},
'3B': {'OS': 'THEOS','Description': 'THEOS v4 extended'},
'3C': {'OS': 'PartitionMagic','Description': 'PqRP (image in progress)'},
'3D': {'OS': 'PartitionMagic','Description': 'Hidden NetWare'},
'3F': {'OS': 'OS/32','Description': 'Unknown'},
'40': {'OS': 'PICK / Venix','Description': 'PICK R83 / Venix 80286'},
'41': {'OS': 'RISC / Linux / PowerPC','Description': 'Boot / Old Linux/Minix'},
'42': {'OS': 'SFS / Linux / Win2K/XP/etc','Description': 'SFS / Old Linux Swap'},
'43': {'OS': 'Linux','Description': 'Old Linux native'},
'44': {'OS': 'GoBack','Description': 'Norton/WildFire/Adaptec/Roxio'},
'45': {'OS': 'Boot-US / EUMEL/ELAN','Description': 'Priam/Boot/EUMEL/ELAN (L2)'},
'46': {'OS': 'EUMEL/ELAN','Description': 'EUMEL/ELAN (L2)'},
'47': {'OS': 'EUMEL/ELAN','Description': 'EUMEL/ELAN (L2)'},
'48': {'OS': 'EUMEL/ELAN','Description': 'EUMEL/ELAN (L2), ERGOS L3'},
'4A': {'OS': 'AdaOS / ALFS/THIN','Description': 'Aquila / ALFS/THIN'},
'4C': {'OS': 'ETH Oberon','Description': 'Aos (A2) file system (76)'},
'4D': {'OS': 'QNX Neutrino','Description': 'Primary QNX POSIX volume'},
'4E': {'OS': 'QNX Neutrino','Description': 'Secondary QNX POSIX volume'},
'4F': {'OS': 'QNX Neutrino / ETH Oberon','Description': '3rd QNX POSIX/Boot/Native'},
'50': {'OS': 'DiskMan4/ETH/LynxOS/Novell','Description': 'Alt FS/Read-only/Lynx RTOS'},
'51': {'OS': 'Disk Manager 4-6','Description': 'R/W partition (Aux 1)'},
'52': {'OS': 'CP/M-80/ System V/AT, V/386','Description': 'CP/M-80'},
'53': {'OS': 'Disk Manager 6','Description': 'Auxiliary 3 (WO)'},
'54': {'OS': 'Disk Manager 6','Description': 'Dynamic Drive Overlay (DDO)'},
'55': {'OS': 'EZ-Drive','Description': 'Maxtor/MaxBlast/DriveGuide'},
'56': {'OS': 'AT&T DOS/EZ-Drive/VFeature','Description': 'FAT12~16/EZ-BIOS/VFeature'},
'57': {'OS': 'DrivePro','Description': 'VNDI partition'},
'5C': {'OS': 'EDISK','Description': 'Priam EDisk Volume'},
'61': {'OS': 'SpeedStor','Description': 'Unknown'},
'63': {'OS': 'Unix','Description': 'Unix,ISC,SysV,ix,BSD,HURD'},
'64': {'OS': 'SpeedStor / NetWare','Description': 'NetWare FS 286/2,PC-ARMOUR'},
'65': {'OS': 'NetWare','Description': 'NetWare File System 386'},
'66': {'OS': 'NetWare / NetWare','Description': 'NetWare FS 386 / SMS'},
'67': {'OS': 'NetWare','Description': 'Wolf Mountain'},
'68': {'OS': 'NetWare','Description': 'Unknown'},
'69': {'OS': 'NetWare 5 / NetWare','Description': 'Novell Storage Services'},
'6E': {'Description': 'Unknown'},
'70': {'OS': 'DiskSecure','Description': 'DiskSecure multiboot'},
'71': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'72': {'OS': 'APTI systems / Unix V7/x86','Description': 'APTI altFAT12 / V7 / x86'},
'73': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'74': {'OS': 'Microsoft, IBM','Description': 'Reserved / Scramdisk'},
'75': {'OS': 'PC/IX','Description': 'Unknown'},
'76': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'77': {'OS': 'Novell','Description': 'VNDI, M2FS, M2CS'},
'78': {'OS': 'Geurt Vos','Description': 'XOSL bootloader file system'},
'79': {'OS': 'APTI conformant systems','Description': 'APTI altFAT16 (CHS, SFN)'},
'7A': {'OS': 'APTI conformant systems','Description': 'APTI altFAT16 (LBA, SFN)'},
'7B': {'OS': 'APTI conformant systems','Description': 'APTI altFAT16B (CHS, SFN)'},
'7C': {'OS': 'APTI conformant systems','Description': 'APTI altFAT32 (LBA, SFN)'},
'7D': {'OS': 'APTI conformant systems','Description': 'APTI altFAT32 (CHS, SFN)'},
'7E': {'OS': 'F.I.X. (claim) / PrimoCache','Description': 'Level 2 cache'},
'7F': {'OS': 'Varies','Description': 'AltOS DevPartition Standard'},
'80': {'OS': 'Minix 1.1-1.4a','Description': 'Minix file system (old)'},
'81': {'OS': 'Minix 1.4b+ / Linux','Description': 'MINIX FS/Mitac AdvDiskManager'},
'82': {'OS': 'Linux / Sun Microsystems','Description': 'Swap / Solaris x86 / Prime'},
'83': {'OS': 'GNU/Linux','Description': 'Any native Linux FS'},
'84': {'OS': 'OS/2 / Windows 7','Description': 'Hibernat/HiddenC/RapidStart'},
'85': {'OS': 'GNU/Linux','Description': 'Linux extended'},
'86': {'OS': 'Windows NT 4 Server / Linux','Description': 'FAT16B mirror/LinuxRAID-old'},
'87': {'OS': 'Windows NT 4 Server','Description': 'HPFS/NTFS mirrored volume'},
'88': {'OS': 'GNU/Linux','Description': 'Plaintext partition table'},
'8A': {'OS': 'AiR-BOOT','Description': 'Linux kernel image'},
'8B': {'OS': 'Windows NT 4 Server','Description': 'FAT32 mirrored volume set'},
'8C': {'OS': 'Windows NT 4 Server','Description': 'FAT32 mirrored volume set'},
'8D': {'OS': 'Free FDISK','Description': 'Hidden FAT12'},
'8E': {'OS': 'Linux','Description': 'Linux LVM'},
'90': {'OS': 'Free FDISK','Description': 'Hidden FAT16'},
'91': {'OS': 'Free FDISK','Description': 'Hidden extended partition'},
'92': {'OS': 'Free FDISK','Description': 'Hidden FAT16B'},
'93': {'OS': 'Amoeba / Linux','Description': 'Amoeba native/Hidden Linux'},
'94': {'OS': 'Amoeba','Description': 'Amoeba bad block table'},
'95': {'OS': 'EXOPC','Description': 'EXOPC native'},
'96': {'OS': 'CHRP','Description': 'ISO-9660 file system'},
'97': {'OS': 'Free FDISK','Description': 'Hidden FAT32'},
'98': {'OS': 'Free FDISK / ROM-DOS','Description': 'Hidden FAT32 / service part'},
'99': {'OS': 'early Unix','Description': 'Unknown'},
'9A': {'OS': 'Free FDISK','Description': 'Hidden FAT16'},
'9B': {'OS': 'Free FDISK','Description': 'Hidden extended partition'},
'9E': {'OS': 'VSTA / ForthOS','Description': 'ForthOS (eForth port)'},
'9F': {'OS': 'BSD/OS 3.0+, BSDI','Description': 'Unknown'},
'A0': {'OS': 'HP/Phoenix/IBM/Toshiba/Sony','Description': 'Diagnostic for HP/Hibernate'},
'A1': {'OS': 'HP / Phoenix, NEC','Description': 'HP Vol Expansion/Hibernate'},
'A2': {'OS': 'Cyclone V','Description': 'Hard Processor System (HPS)'},
'A3': {'OS': 'HP','Description': 'HP Vol Expansion(SpeedStor)'},
'A4': {'OS': 'HP','Description': 'HP Vol Expansion(SpeedStor)'},
'A5': {'OS': 'BSD','Description': 'BSD slice'},
'A6': {'OS': 'OpenBSD','Description': 'HP Vol Expansion/BSD slice'},
'A7': {'OS': 'NeXT','Description': 'NeXTSTEP'},
'A8': {'OS': 'Darwin, Mac OS X','Description': 'Apple Darwin, Mac OS X UFS'},
'A9': {'OS': 'NetBSD','Description': 'NetBSD slice'},
'AA': {'OS': 'MS-DOS','Description': 'Olivetti DOS FAT12(1.44 MB)'},
'AB': {'OS': 'Darwin, Mac OS X / GO! OS','Description': 'Apple Darwin/OS X boot/GO!'},
'AD': {'OS': 'RISC OS','Description': 'ADFS / FileCore format'},
'AE': {'OS': 'ShagOS','Description': 'ShagOS file system'},
'AF': {'OS': 'ShagOS','Description': 'OS X HFS & HFS+/ShagOS Swap'},
'B0': {'OS': 'Boot-Star','Description': 'Boot-Star dummy partition'},
'B1': {'OS': 'QNX 6.x','Description': 'HPVolExpansion/QNX Neutrino'},
'B2': {'OS': 'QNX 6.x','Description': 'QNX Neutrino power-safe FS'},
'B3': {'OS': 'QNX 6.x','Description': 'HPVolExpansion/QNX Neutrino'},
'B4': {'OS': 'HP','Description': 'HP Vol Expansion(SpeedStor)'},
'B6': {'OS': 'Windows NT 4 Server','Description': 'HPVolExpansion/FAT16Bmirror'},
'B7': {'OS': 'BSDI / Windows NT 4 Server','Description': 'BSDI,Swap,HPFS/NTFS mirror'},
'B8': {'OS': 'BSDI (before 3.0)','Description': 'BSDI Swap / native FS'},
'BB': {'OS': 'Acronis/BootWizard/WinNT 4','Description': 'BootWizard/OEM/FAT32 mirror'},
'BC': {'OS': 'Acronis/WinNT/BackupCapsule','Description': 'FAT32RAID/SecureZone/Backup'},
'BD': {'OS': 'BonnyDOS/286','Description': 'Unknown'},
'BE': {'OS': 'Solaris 8','Description': 'Solaris 8 boot'},
'BF': {'OS': 'Solaris','Description': 'Solaris x86'},
'C0': {'OS': 'DR-DOS,MultiuserDOS,REAL/32','Description': 'Secured FAT (under 32 MB)'},
'C1': {'OS': 'DR DOS','Description': 'Secured FAT12'},
'C2': {'OS': 'Power Boot','Description': 'Hidden Linux native FS'},
'C3': {'OS': 'Power Boot','Description': 'Hidden Linux Swap'},
'C4': {'OS': 'DR DOS','Description': 'Secured FAT16'},
'C5': {'OS': 'DR DOS','Description': 'Secured extended partition'},
'C6': {'OS': 'DR DOS / WinNT 4 Server','Description': 'Secured FAT16B/FAT16Bmirror'},
'C7': {'OS': 'Syrinx / WinNT 4 Server','Description': 'Syrinx boot/HPFS/NTFSmirror'},
'C8': {'Description': "DR-DOS Reserved (since '97)"},
'C9': {'Description': "DR-DOS Reserved (since '97)"},
'CA': {'Description': "DR-DOS Reserved (since '97)"},
'CB': {'OS': 'DR-DOSx / WinNT 4 Server','Description': 'Secured FAT32/FAT32 mirror'},
'CC': {'OS': 'DR-DOSx / WinNT 4 Server','Description': 'Secured FAT32/FAT32 mirror'},
'CD': {'OS': 'CTOS','Description': 'Memory dump'},
'CE': {'OS': 'DR-DOSx','Description': 'Secured FAT16B'},
'CF': {'OS': 'DR-DOSx','Description': 'Secured extended partition'},
'D0': {'OS': 'Multiuser DOS, REAL/32','Description': 'Secured FAT (over 32 MB)'},
'D1': {'OS': 'Multiuser DOS','Description': 'Secured FAT12'},
'D4': {'OS': 'Multiuser DOS','Description': 'Secured FAT16'},
'D5': {'OS': 'Multiuser DOS','Description': 'Secured extended partition'},
'D6': {'OS': 'Multiuser DOS','Description': 'Secured FAT16B'},
'D8': {'OS': 'Digital Research','Description': 'CP/M-86 [citation needed]'},
'DA': {'OS': 'Powercopy Backup','Description': 'Non-FS data / Shielded disk'},
'DB': {'OS': 'CP/M-86/CDOS/CTOS/D800/DRMK','Description': 'CP/M-86/ConcDOS/Boot/FAT32'},
'DD': {'OS': 'CTOS','Description': 'Hidden memory dump'},
'DE': {'OS': 'Dell','Description': 'FAT16 utility/diagnostic'},
'DF': {'OS': 'DG/UX / BootIt / Aviion','Description': 'DG/UX Virt DiskMan / EMBRM'},
'E0': {'OS': 'STMicroelectronics','Description': 'ST AVFS'},
'E1': {'OS': 'SpeedStor','Description': 'ExtendedFAT12 >1023cylinder'},
'E2': {'Description': 'DOS read-only (XFDISK)'},
'E3': {'OS': 'SpeedStor','Description': 'DOS read-only'},
'E4': {'OS': 'SpeedStor','Description': 'ExtendedFAT16 <1024cylinder'},
'E5': {'OS': 'Tandy MS-DOS','Description': 'Logical FAT12 or FAT16'},
'E6': {'OS': 'SpeedStor','Description': 'Unknown'},
'E8': {'OS': 'LUKS','Description': 'Linux Unified Key Setup'},
'EB': {'OS': 'BeOS, Haiku','Description': 'BFS'},
'EC': {'OS': 'SkyOS','Description': 'SkyFS'},
'ED': {'OS': 'Sprytix / EDD 4','Description': 'EDC loader / GPT hybrid MBR'},
'EE': {'OS': 'EFI','Description': 'GPT protective MBR'},
'EF': {'OS': 'EFI','Description': 'EFI system partition'},
'F0': {'OS': 'Linux / OS/32','Description': 'PA-RISC Linux boot loader.'},
'F1': {'OS': 'SpeedStor','Description': 'Unknown'},
'F2': {'OS': 'SperryIT DOS/Unisys DOS','Description': 'Logical FAT12/FAT16'},
'F3': {'OS': 'SpeedStor','Description': 'Unknown'},
'F4': {'OS': 'SpeedStor / Prologue','Description': '"large"DOS part/NGF/TwinFS'},
'F5': {'OS': 'Prologue','Description': 'MD0-MD9 part for NGF/TwinFS'},
'F6': {'OS': 'SpeedStor','Description': 'Unknown'},
'F7': {'OS': 'O.S.G. / X1','Description': 'EFAT / Solid State FS'},
'F9': {'OS': 'Linux','Description': 'pCache ext2/ext3 cache'},
'FA': {'OS': 'Bochs','Description': 'x86 emulator'},
'FB': {'OS': 'VMware','Description': 'VMware VMFS partition'},
'FC': {'OS': 'VMware','Description': 'Swap / VMKCORE kernel dump'},
'FD': {'OS': 'Linux / FreeDOS','Description': 'LinuxRAID/Reserved4FreeDOS'},
'FE': {'OS': 'SpeedStor/LANstep/NT/Linux','Description': 'PS/2/DiskAdmin/old LinuxLVM'},
'FF': {'OS': 'XENIX','Description': 'XENIX bad block table'},
'00000000-0000-0000-0000-000000000000': {'Description': 'Unused entry'},
'024DEE41-33E7-11D3-9D69-0008C781F39F': {'Description': 'MBR partition scheme'},
'C12A7328-F81F-11D2-BA4B-00A0C93EC93B': {'Description': 'EFI System partition'},
'21686148-6449-6E6F-744E-656564454649': {'Description': 'BIOS Boot partition'},
'D3BFE2DE-3DAF-11DF-BA40-E3A556D89593': {'Description': 'Intel Fast Flash (iFFS) partition (for Intel Rapid Start technology)'},
'F4019732-066E-4E12-8273-346C5641494F': {'Description': 'Sony boot partition'},
'BFBFAFE7-A34F-448A-9A5B-6213EB736C22': {'Description': 'Lenovo boot partition'},
'E3C9E316-0B5C-4DB8-817D-F92DF00215AE': {'OS': 'Windows', 'Description': 'Microsoft Reserved Partition (MSR)'},
'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7': {'OS': 'Windows', 'Description': 'Basic data partition'},
'5808C8AA-7E8F-42E0-85D2-E1E90434CFB3': {'OS': 'Windows', 'Description': 'Logical Disk Manager (LDM) metadata partition'},
'AF9B60A0-1431-4F62-BC68-3311714A69AD': {'OS': 'Windows', 'Description': 'Logical Disk Manager data partition'},
'DE94BBA4-06D1-4D40-A16A-BFD50179D6AC': {'OS': 'Windows', 'Description': 'Windows Recovery Environment'},
'37AFFC90-EF7D-4E96-91C3-2D7AE055B174': {'OS': 'Windows', 'Description': 'IBM General Parallel File System (GPFS) partition'},
'E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D': {'OS': 'Windows', 'Description': 'Storage Spaces partition'},
'75894C1E-3AEB-11D3-B7C1-7B03A0000000': {'OS': 'HP-UX', 'Description': 'Data partition'},
'E2A1E728-32E3-11D6-A682-7B03A0000000': {'OS': 'HP-UX', 'Description': 'Service Partition'},
'0FC63DAF-8483-4772-8E79-3D69D8477DE4': {'OS': 'Linux', 'Description': 'Linux filesystem data'},
'A19D880F-05FC-4D3B-A006-743F0F84911E': {'OS': 'Linux', 'Description': 'RAID partition'},
'44479540-F297-41B2-9AF7-D131D5F0458A': {'OS': 'Linux', 'Description': 'Root partition (x86)'},
'4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709': {'OS': 'Linux', 'Description': 'Root partition (x86-64)'},
'69DAD710-2CE4-4E3C-B16C-21A1D49ABED3': {'OS': 'Linux', 'Description': 'Root partition (32-bit ARM)'},
'B921B045-1DF0-41C3-AF44-4C6F280D3FAE': {'OS': 'Linux', 'Description': 'Root partition (64-bit ARM)/AArch64)'},
'0657FD6D-A4AB-43C4-84E5-0933C84B4F4F': {'OS': 'Linux', 'Description': 'Swap partition'},
'E6D6D379-F507-44C2-A23C-238F2A3DF928': {'OS': 'Linux', 'Description': 'Logical Volume Manager (LVM) partition'},
'933AC7E1-2EB4-4F13-B844-0E14E2AEF915': {'OS': 'Linux', 'Description': '/home partition'},
'3B8F8425-20E0-4F3B-907F-1A25A76F98E8': {'OS': 'Linux', 'Description': '/srv (server data) partition'},
'7FFEC5C9-2D00-49B7-8941-3EA10A5586B7': {'OS': 'Linux', 'Description': 'Plain dm-crypt partition'},
'CA7D7CCB-63ED-4C53-861C-1742536059CC': {'OS': 'Linux', 'Description': 'LUKS partition'},
'8DA63339-0007-60C0-C436-083AC8230908': {'OS': 'Linux', 'Description': 'Reserved'},
'83BD6B9D-7F41-11DC-BE0B-001560B84F0F': {'OS': 'FreeBSD', 'Description': 'Boot partition'},
'516E7CB4-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Data partition'},
'516E7CB5-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Swap partition'},
'516E7CB6-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Unix File System (UFS) partition'},
'516E7CB8-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Vinum volume manager partition'},
'516E7CBA-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'ZFS partition'},
'48465300-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Hierarchical File System Plus (HFS+) partition'},
'55465300-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple UFS'},
'6A898CC3-1DD2-11B2-99A6-080020736631': {'OS': 'OS X Darwin', 'Description': 'ZFS'},
'52414944-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple RAID partition'},
'52414944-5F4F-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple RAID partition, offline'},
'426F6F74-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple Boot partition (Recovery HD)'},
'4C616265-6C00-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple Label'},
'5265636F-7665-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple TV Recovery partition'},
'53746F72-6167-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple Core Storage (i.e. Lion FileVault) partition'},
'6A82CB45-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Boot partition'},
'6A85CF4D-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Root partition'},
'6A87C46F-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Swap partition'},
'6A8B642B-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Backup partition'},
'6A898CC3-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': '/usr partition'},
'6A8EF2E9-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': '/var partition'},
'6A90BA39-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': '/home partition'},
'6A9283A5-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Alternate sector'},
'6A945A3B-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Reserved partition'},
'6A9630D1-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'6A980767-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'6A96237F-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'6A8D2AC7-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'49F48D32-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'Swap partition'},
'49F48D5A-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'FFS partition'},
'49F48D82-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'LFS partition'},
'49F48DAA-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'RAID partition'},
'2DB519C4-B10F-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'Concatenated partition'},
'2DB519EC-B10F-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'Encrypted partition'},
'FE3A2A5D-4F32-41A7-B725-ACCC3285A309': {'OS': 'ChromeOS', 'Description': 'ChromeOS kernel'},
'3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC': {'OS': 'ChromeOS', 'Description': 'ChromeOS rootfs'},
'2E0A753D-9E48-43B0-8337-B15192CB1B5E': {'OS': 'ChromeOS', 'Description': 'ChromeOS future use'},
'42465331-3BA3-10F1-802A-4861696B7521': {'OS': 'Haiku', 'Description': 'Haiku BFS'},
'85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Boot partition'},
'85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Data partition'},
'85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Swap partition'},
'0394EF8B-237E-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Unix File System (UFS) partition'},
'85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Vinum volume manager partition'},
'85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'ZFS partition'},
'45B0969E-9B03-4F30-B4C6-B4B80CEFF106': {'OS': 'Ceph', 'Description': 'Ceph Journal'},
'45B0969E-9B03-4F30-B4C6-5EC00CEFF106': {'OS': 'Ceph', 'Description': 'Ceph dm-crypt Encrypted Journal'},
'4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D': {'OS': 'Ceph', 'Description': 'Ceph OSD'},
'4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D': {'OS': 'Ceph', 'Description': 'Ceph dm-crypt OSD'},
'89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE': {'OS': 'Ceph', 'Description': 'Ceph disk in creation'},
'89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE': {'OS': 'Ceph', 'Description': 'Ceph dm-crypt disk in creation'},
'824CC7A0-36A8-11E3-890A-952519AD3F61': {'OS': 'OpenBSD', 'Description': 'Data partition'},
'CEF5A9AD-73BC-4601-89F3-CDEEEEE321A1': {'OS': 'QNX', 'Description': 'Power-safe (QNX6) file system'},
'C91818F9-8025-47AF-89D2-F030D7000C2C': {'OS': 'Plan 9', 'Description': 'Plan 9 partition'},
'9D275380-40AD-11DB-BF97-000C2911D1B8': {'OS': 'VMware ESX', 'Description': 'vmkcore (coredump partition)'},
'AA31E02A-400F-11DB-9590-000C2911D1B8': {'OS': 'VMware ESX', 'Description': 'VMFS filesystem partition'},
'9198EFFC-31C0-11DB-8F78-000C2911D1B8': {'OS': 'VMware ESX', 'Description': 'VMware Reserved'},
'2568845D-2332-4675-BC39-8FA5A4748D15': {'OS': 'Android-IA', 'Description': 'Bootloader'},
'114EAFFE-1552-4022-B26E-9B053604CF84': {'OS': 'Android-IA', 'Description': 'Bootloader2'},
'49A4D17F-93A3-45C1-A0DE-F50B2EBE2599': {'OS': 'Android-IA', 'Description': 'Boot'},
'4177C722-9E92-4AAB-8644-43502BFD5506': {'OS': 'Android-IA', 'Description': 'Recovery'},
'EF32A33B-A409-486C-9141-9FFB711F6266': {'OS': 'Android-IA', 'Description': 'Misc'},
'20AC26BE-20B7-11E3-84C5-6CFDB94711E9': {'OS': 'Android-IA', 'Description': 'Metadata'},
'38F428E6-D326-425D-9140-6E0EA133647C': {'OS': 'Android-IA', 'Description': 'System'},
'A893EF21-E428-470A-9E55-0668FD91A2D9': {'OS': 'Android-IA', 'Description': 'Cache'},
'DC76DDA9-5AC1-491C-AF42-A82591580C0D': {'OS': 'Android-IA', 'Description': 'Data'},
'EBC597D0-2053-4B15-8B64-E0AAC75F4DB1': {'OS': 'Android-IA', 'Description': 'Persistent'},
'8F68CC74-C5E5-48DA-BE91-A0C8C15E9C80': {'OS': 'Android-IA', 'Description': 'Factory'},
'767941D0-2085-11E3-AD3B-6CFDB94711E9': {'OS': 'Android-IA', 'Description': 'Fastboot / Tertiary'},
'AC6D7924-EB71-4DF8-B48D-E267B27148FF': {'OS': 'Android-IA', 'Description': 'OEM'},
'7412F7D5-A156-4B13-81DC-867174929325': {'OS': 'ONIE', 'Description': 'Boot'},
'D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149': {'OS': 'ONIE', 'Description': 'Config'},
'9E1A2D38-C612-4316-AA26-8B49521E5A8B': {'OS': 'PowerPC', 'Description': 'PReP boot'},
'BC13C2FF-59E6-4262-A352-B275FD6F7172': {'OS': 'Freedesktop', 'Description': 'Extended Boot Partition ($BOOT)'},
}
def lookup_guid(guid):
return PARTITION_UIDS.get(guid.upper(), {})
if __name__ == '__main__':
print("This file is not meant to be called directly.")

View file

@ -2,110 +2,119 @@
from functions.common import *
# Regex
REGEX_REGISTRY_DIRS = re.compile(
r'^(config$|RegBack$|System32$|Transfer|Win)',
re.IGNORECASE)
r'^(config$|RegBack$|System32$|Transfer|Win)',
re.IGNORECASE)
REGEX_SOFTWARE_HIVE = re.compile(r'^Software$', re.IGNORECASE)
def extract_keys():
"""Extract keys from provided hives and return a dict."""
keys = {}
"""Extract keys from provided hives and return a dict."""
keys = {}
# Extract keys
extract_item('ProduKey', silent=True)
for hive in find_software_hives():
cmd = [
global_vars['Tools']['ProduKey'],
'/IEKeys', '0',
'/WindowsKeys', '1',
'/OfficeKeys', '1',
'/ExtractEdition', '1',
'/nosavereg',
'/regfile', hive,
'/scomma', '']
try:
out = run_program(cmd)
except subprocess.CalledProcessError:
# Ignore and return empty dict
pass
else:
for line in out.stdout.decode().splitlines():
# Add key to keys under product only if unique
tmp = line.split(',')
product = tmp[0]
key = tmp[2]
if product not in keys:
keys[product] = []
if key not in keys[product]:
keys[product].append(key)
# Extract keys
extract_item('ProduKey', silent=True)
for hive in find_software_hives():
cmd = [
global_vars['Tools']['ProduKey'],
'/IEKeys', '0',
'/WindowsKeys', '1',
'/OfficeKeys', '1',
'/ExtractEdition', '1',
'/nosavereg',
'/regfile', hive,
'/scomma', '']
try:
out = run_program(cmd)
except subprocess.CalledProcessError:
# Ignore and return empty dict
pass
else:
for line in out.stdout.decode().splitlines():
# Add key to keys under product only if unique
tmp = line.split(',')
product = tmp[0]
key = tmp[2]
if product not in keys:
keys[product] = []
if key not in keys[product]:
keys[product].append(key)
# Done
return keys
# Done
return keys
def list_clientdir_keys():
"""List product keys found in hives inside the ClientDir."""
keys = extract_keys()
key_list = []
if keys:
for product in sorted(keys):
key_list.append(product)
for key in sorted(keys[product]):
key_list.append(' {key}'.format(key=key))
else:
key_list.append('No keys found.')
"""List product keys found in hives inside the ClientDir."""
keys = extract_keys()
key_list = []
if keys:
for product in sorted(keys):
key_list.append(product)
for key in sorted(keys[product]):
key_list.append(' {key}'.format(key=key))
else:
key_list.append('No keys found.')
return key_list
return key_list
def find_software_hives():
"""Search for transferred SW hives and return a list."""
hives = []
search_paths = [global_vars['ClientDir']]
"""Search for transferred SW hives and return a list."""
hives = []
search_paths = [global_vars['ClientDir']]
while len(search_paths) > 0:
for item in os.scandir(search_paths.pop(0)):
if item.is_dir() and REGEX_REGISTRY_DIRS.search(item.name):
search_paths.append(item.path)
if item.is_file() and REGEX_SOFTWARE_HIVE.search(item.name):
hives.append(item.path)
while len(search_paths) > 0:
for item in os.scandir(search_paths.pop(0)):
if item.is_dir() and REGEX_REGISTRY_DIRS.search(item.name):
search_paths.append(item.path)
if item.is_file() and REGEX_SOFTWARE_HIVE.search(item.name):
hives.append(item.path)
return hives
return hives
def get_product_keys():
"""List product keys from saved report."""
keys = []
log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars)
with open (log_file, 'r') as f:
for line in f.readlines():
if re.search(r'^Product Name', line):
line = re.sub(r'^Product Name\s+:\s+(.*)', r'\1', line.strip())
keys.append(line)
"""List product keys from saved report."""
keys = []
log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars)
with open (log_file, 'r') as f:
for line in f.readlines():
if re.search(r'^Product Name', line):
line = re.sub(r'^Product Name\s+:\s+(.*)', r'\1', line.strip())
keys.append(line)
if keys:
return keys
else:
return ['No product keys found']
if keys:
return keys
else:
return ['No product keys found']
def run_produkey():
"""Run ProduKey and save report in the ClientDir."""
extract_item('ProduKey', silent=True)
log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars)
if not os.path.exists(log_file):
# Clear current configuration
for config in ['ProduKey.cfg', 'ProduKey64.cfg']:
config = r'{BinDir}\ProduKey\{config}'.format(
config=config, **global_vars)
try:
if os.path.exists(config):
os.remove(config)
except Exception:
pass
cmd = [
global_vars['Tools']['ProduKey'],
'/nosavereg',
'/stext',
log_file]
run_program(cmd, check=False)
"""Run ProduKey and save report in the ClientDir."""
extract_item('ProduKey', silent=True)
log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars)
if not os.path.exists(log_file):
# Clear current configuration
for config in ['ProduKey.cfg', 'ProduKey64.cfg']:
config = r'{BinDir}\ProduKey\{config}'.format(
config=config, **global_vars)
try:
if os.path.exists(config):
os.remove(config)
except Exception:
pass
cmd = [
global_vars['Tools']['ProduKey'],
'/nosavereg',
'/stext',
log_file]
run_program(cmd, check=False)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -2,125 +2,135 @@
from functions.common import *
def run_chkdsk(repair=False):
"""Run CHKDSK scan or schedule offline repairs."""
if repair:
run_chkdsk_offline()
else:
run_chkdsk_scan()
"""Run CHKDSK scan or schedule offline repairs."""
if repair:
run_chkdsk_offline()
else:
run_chkdsk_scan()
def run_chkdsk_scan():
"""Run CHKDSK in a "split window" and report errors."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE'], '/scan', '/perf']
else:
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False)
# retcode == 0: no issues
# retcode == 1: fixed issues (also happens when chkdsk.exe is killed?)
# retcode == 2: issues
if int(out.returncode) > 0:
# print_error(' ERROR: CHKDSK encountered errors')
raise GenericError
"""Run CHKDSK in a "split window" and report errors."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE'], '/scan', '/perf']
else:
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False)
# retcode == 0: no issues
# retcode == 1: fixed issues (also happens when chkdsk.exe is killed?)
# retcode == 2: issues
if int(out.returncode) > 0:
# print_error(' ERROR: CHKDSK encountered errors')
raise GenericError
# Save stderr
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}\Tools\CHKDSK.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode().splitlines():
f.write(line.strip() + '\n')
# Save stderr
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}\Tools\CHKDSK.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode().splitlines():
f.write(line.strip() + '\n')
def run_chkdsk_offline():
"""Set filesystem 'dirty bit' to force a chkdsk during next boot."""
cmd = [
'fsutil', 'dirty',
'set',
global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False)
if int(out.returncode) > 0:
raise GenericError
"""Set filesystem 'dirty bit' to force a chkdsk during next boot."""
cmd = [
'fsutil', 'dirty',
'set',
global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False)
if int(out.returncode) > 0:
raise GenericError
def run_dism(repair=False):
"""Run DISM /RestoreHealth, then /CheckHealth, and then report errors."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
if repair:
# Restore Health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/RestoreHealth',
r'/LogPath:"{LogDir}\Tools\DISM_RestoreHealth.log"'.format(
**global_vars),
'-new_console:n', '-new_console:s33V']
else:
# Scan Health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/ScanHealth',
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)
wait_for_process('dism')
# Now check health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/CheckHealth',
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():
raise GenericError
"""Run DISM to either scan or repair component store health."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
if repair:
# Restore Health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/RestoreHealth',
r'/LogPath:"{LogDir}\Tools\DISM_RestoreHealth.log"'.format(
**global_vars),
'-new_console:n', '-new_console:s33V']
else:
raise UnsupportedOSError
# Scan Health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/ScanHealth',
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)
wait_for_process('dism')
# Now check health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/CheckHealth',
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():
raise GenericError
else:
raise UnsupportedOSError
def run_kvrt():
"""Run KVRT."""
extract_item('KVRT', silent=True)
os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
cmd = [
global_vars['Tools']['KVRT'],
'-accepteula', '-dontcryptsupportinfo', '-fixednames',
'-d', global_vars['QuarantineDir'],
'-processlevel', '3']
popen_program(cmd, pipe=False)
"""Run KVRT."""
extract_item('KVRT', silent=True)
os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
cmd = [
global_vars['Tools']['KVRT'],
'-accepteula', '-dontcryptsupportinfo', '-fixednames',
'-d', global_vars['QuarantineDir'],
'-processlevel', '3']
popen_program(cmd, pipe=False)
def run_sfc_scan():
"""Run SFC in a "split window" and report errors."""
cmd = [
r'{SYSTEMROOT}\System32\sfc.exe'.format(**global_vars['Env']),
'/scannow']
out = run_program(cmd, check=False)
# Save stderr
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}\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
log_text = out.stdout.decode('utf-8', 'ignore').replace('\0', '')
if re.findall(r'did\s+not\s+find\s+any\s+integrity\s+violations', log_text):
pass
elif re.findall(r'successfully\s+repaired\s+them', log_text):
raise GenericRepair
else:
raise GenericError
"""Run SFC in a "split window" and report errors."""
cmd = [
r'{SYSTEMROOT}\System32\sfc.exe'.format(**global_vars['Env']),
'/scannow']
out = run_program(cmd, check=False)
# Save stderr
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}\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
log_text = out.stdout.decode('utf-8', 'ignore').replace('\0', '')
if re.findall(r'did\s+not\s+find\s+any\s+integrity\s+violations', log_text):
pass
elif re.findall(r'successfully\s+repaired\s+them', log_text):
raise GenericRepair
else:
raise GenericError
def run_tdsskiller():
"""Run TDSSKiller."""
extract_item('TDSSKiller', silent=True)
os.makedirs(r'{QuarantineDir}\TDSSKiller'.format(
**global_vars), exist_ok=True)
cmd = [
global_vars['Tools']['TDSSKiller'],
'-l', r'{LogDir}\Tools\TDSSKiller.log'.format(**global_vars),
'-qpath', r'{QuarantineDir}\TDSSKiller'.format(**global_vars),
'-accepteula', '-accepteulaksn',
'-dcexact', '-tdlfs']
run_program(cmd, pipe=False)
"""Run TDSSKiller."""
extract_item('TDSSKiller', silent=True)
os.makedirs(r'{QuarantineDir}\TDSSKiller'.format(
**global_vars), exist_ok=True)
cmd = [
global_vars['Tools']['TDSSKiller'],
'-l', r'{LogDir}\Tools\TDSSKiller.log'.format(**global_vars),
'-qpath', r'{QuarantineDir}\TDSSKiller'.format(**global_vars),
'-accepteula', '-accepteulaksn',
'-dcexact', '-tdlfs']
run_program(cmd, pipe=False)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -2,35 +2,44 @@
from functions.common import *
# STATIC VARIABLES
REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer'
def disable_safemode_msi():
"""Disable MSI access under safemode."""
cmd = ['reg', 'delete', REG_MSISERVER, '/f']
run_program(cmd)
"""Disable MSI access under safemode."""
cmd = ['reg', 'delete', REG_MSISERVER, '/f']
run_program(cmd)
def disable_safemode():
"""Edit BCD to remove safeboot value."""
cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot']
run_program(cmd)
"""Edit BCD to remove safeboot value."""
cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot']
run_program(cmd)
def enable_safemode_msi():
"""Enable MSI access under safemode."""
cmd = ['reg', 'add', REG_MSISERVER, '/f']
run_program(cmd)
cmd = ['reg', 'add', REG_MSISERVER, '/ve',
'/t', 'REG_SZ', '/d', 'Service', '/f']
run_program(cmd)
"""Enable MSI access under safemode."""
cmd = ['reg', 'add', REG_MSISERVER, '/f']
run_program(cmd)
cmd = ['reg', 'add', REG_MSISERVER, '/ve',
'/t', 'REG_SZ', '/d', 'Service', '/f']
run_program(cmd)
def enable_safemode():
"""Edit BCD to set safeboot as default."""
cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network']
run_program(cmd)
"""Edit BCD to set safeboot as default."""
cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network']
run_program(cmd)
def reboot(delay=3):
cmd = ['shutdown', '-r', '-t', '{}'.format(delay)]
run_program(cmd, check=False)
cmd = ['shutdown', '-r', '-t', '{}'.format(delay)]
run_program(cmd, check=False)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,243 @@
'''Wizard Kit: Functions - Sensors'''
# pylint: disable=no-name-in-module,wildcard-import
# vim: sts=2 sw=2 ts=2
import json
import re
from functions.tmux import *
from settings.sensors import *
# Error Classes
class ThermalLimitReachedError(Exception):
'''Thermal limit reached error.'''
def clear_temps(sensor_data):
"""Clear saved temps but keep structure, returns dict."""
for _section, _adapters in sensor_data.items():
for _adapter, _sources in _adapters.items():
for _source, _data in _sources.items():
_data['Temps'] = []
def fix_sensor_str(_s):
"""Cleanup string and return str."""
_s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', _s, re.IGNORECASE)
_s = _s.title()
_s = _s.replace('Coretemp', 'CPUTemp')
_s = _s.replace('Acpi', 'ACPI')
_s = _s.replace('ACPItz', 'ACPI TZ')
_s = _s.replace('Isa ', 'ISA ')
_s = _s.replace('Pci ', 'PCI ')
_s = _s.replace('Id ', 'ID ')
_s = re.sub(r'(\D+)(\d+)', r'\1 \2', _s, re.IGNORECASE)
_s = re.sub(r'^K (\d+)Temp', r'AMD K\1 Temps', _s, re.IGNORECASE)
_s = re.sub(r'T(ctl|die)', r'CPU (T\1)', _s, re.IGNORECASE)
return _s
def generate_sensor_report(
sensor_data, *temp_labels,
colors=True, cpu_only=False):
"""Generate report based on temp_labels, returns list if str."""
report = []
for _section, _adapters in sorted(sensor_data.items()):
# CPU temps then Other temps
if cpu_only and 'CPU' not in _section:
continue
for _adapter, _sources in sorted(_adapters.items()):
# Adapter
report.append(fix_sensor_str(_adapter))
for _source, _data in sorted(_sources.items()):
# Source
_line = '{:18} '.format(fix_sensor_str(_source))
# Temps (skip label for Current)
for _label in temp_labels:
_line += '{}{}{} '.format(
_label.lower() if _label != 'Current' else '',
': ' if _label != 'Current' else '',
get_temp_str(_data.get(_label, '???'), colors=colors))
report.append(_line)
if not cpu_only:
report.append(' ')
# Handle empty reports (i.e. no sensors detected)
if not report:
report = [
'{}WARNING: No sensors found{}'.format(
COLORS['YELLOW'] if colors else '',
COLORS['CLEAR'] if colors else ''),
' ',
'Please monitor temps manually']
# Done
return report
def get_colored_temp_str(temp):
"""Get colored string based on temp, returns str."""
try:
temp = float(temp)
except ValueError:
return '{YELLOW}{temp}{CLEAR}'.format(temp=temp, **COLORS)
if temp > TEMP_LIMITS['RED']:
color = COLORS['RED']
elif temp > TEMP_LIMITS['ORANGE']:
color = COLORS['ORANGE']
elif temp > TEMP_LIMITS['YELLOW']:
color = COLORS['YELLOW']
elif temp > TEMP_LIMITS['GREEN']:
color = COLORS['GREEN']
elif temp > 0:
color = COLORS['BLUE']
else:
color = COLORS['CLEAR']
return '{color}{prefix}{temp:2.0f}°C{CLEAR}'.format(
color=color,
prefix='-' if temp < 0 else '',
temp=temp,
**COLORS)
def get_raw_sensor_data():
"""Read sensor data and return dict."""
json_data = {}
cmd = ['sensors', '-j']
# Get raw data
try:
result = run_program(cmd)
result = result.stdout.decode('utf-8', errors='ignore').splitlines()
except subprocess.CalledProcessError:
# Assuming no sensors available, set to empty list
result = []
# Workaround for bad sensors
raw_data = []
for line in result:
if line.strip() == ',':
# Assuming malformatted line caused by missing data
continue
raw_data.append(line)
# Parse JSON data
try:
json_data = json.loads('\n'.join(raw_data))
except json.JSONDecodeError:
# Still broken, just return the empty dict
pass
# Done
return json_data
def get_sensor_data():
"""Parse raw sensor data and return new dict."""
json_data = get_raw_sensor_data()
sensor_data = {'CPUTemps': {}, 'Other': {}}
for _adapter, _sources in json_data.items():
if is_cpu_adapter(_adapter):
_section = 'CPUTemps'
else:
_section = 'Other'
sensor_data[_section][_adapter] = {}
_sources.pop('Adapter', None)
# Find current temp and add to dict
## current temp is labeled xxxx_input
for _source, _labels in _sources.items():
for _label, _temp in _labels.items():
if _label.startswith('fan'):
# Skip fan RPMs
continue
if 'input' in _label:
sensor_data[_section][_adapter][_source] = {
'Current': _temp,
'Label': _label,
'Max': _temp,
'Temps': [_temp],
}
# Remove empty sections
for _k, _v in sensor_data.items():
_v = {_k2: _v2 for _k2, _v2 in _v.items() if _v2}
# Done
return sensor_data
def get_temp_str(temp, colors=True):
"""Get temp string, returns str."""
if colors:
return get_colored_temp_str(temp)
try:
temp = float(temp)
except ValueError:
return '{}'.format(temp)
else:
return '{}{:2.0f}°C'.format(
'-' if temp < 0 else '',
temp)
def is_cpu_adapter(adapter):
"""Checks if adapter is a known CPU adapter, returns bool."""
is_cpu = re.search(r'(core|k\d+)temp', adapter, re.IGNORECASE)
return bool(is_cpu)
def monitor_sensors(monitor_pane, monitor_file):
"""Continually update sensor data and report to screen."""
sensor_data = get_sensor_data()
while True:
update_sensor_data(sensor_data)
with open(monitor_file, 'w') as _f:
report = generate_sensor_report(sensor_data, 'Current', 'Max')
_f.write('\n'.join(report))
sleep(1)
if monitor_pane and not tmux_poll_pane(monitor_pane):
break
def save_average_temp(sensor_data, temp_label, seconds=10):
"""Save average temps under temp_label, returns dict."""
clear_temps(sensor_data)
# Get temps
for _i in range(seconds): # pylint: disable=unused-variable
update_sensor_data(sensor_data)
sleep(1)
# Calculate averages
for _section, _adapters in sensor_data.items():
for _adapter, _sources in _adapters.items():
for _source, _data in _sources.items():
_data[temp_label] = sum(_data['Temps']) / len(_data['Temps'])
def update_sensor_data(sensor_data, thermal_limit=None):
"""Read sensors and update existing sensor_data, returns dict."""
json_data = get_raw_sensor_data()
for _section, _adapters in sensor_data.items():
for _adapter, _sources in _adapters.items():
for _source, _data in _sources.items():
try:
_label = _data['Label']
_temp = json_data[_adapter][_source][_label]
_data['Current'] = _temp
_data['Max'] = max(_temp, _data['Max'])
_data['Temps'].append(_temp)
except Exception: # pylint: disable=broad-except
# Dumb workound for Dell sensors with changing source names
pass
# Check if thermal limit reached
if thermal_limit and _section == 'CPUTemps':
if max(_data['Current'], _data['Max']) >= thermal_limit:
raise ThermalLimitReachedError('CPU temps reached limit')
if __name__ == '__main__':
print("This file is not meant to be called directly.")

View file

@ -1,321 +1,359 @@
# Wizard Kit: Functions - Setup
from functions.common import *
from functions.browsers import *
from functions.json import *
from functions.update import *
from settings.setup import *
from settings.sources 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(
os.environ.get('PROGRAMFILES'),
r'Mozilla Firefox\distribution\extensions')
OTHER_RESULTS = {
'Error': {
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
},
'Warning': {}}
SETTINGS_CLASSIC_START = {
r'Software\IvoSoft\ClassicShell\Settings': {},
r'Software\IvoSoft\ClassicStartMenu': {
'DWORD Items': {'ShowedStyle2': 1},
},
r'Software\IvoSoft\ClassicStartMenu\MRU': {},
r'Software\IvoSoft\ClassicStartMenu\Settings': {
'DWORD Items': {'SkipMetro': 1},
'SZ Items': {
'MenuStyle': 'Win7',
'RecentPrograms': 'Recent',
},
},
}
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': {
'DWORD Items': {'AllowTelemetry': 0},
},
r'Software\Microsoft\Windows\CurrentVersion\Policies\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
'WOW64_32': True,
},
r'Software\Policies\Microsoft\Windows\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
},
# Disable Wi-Fi Sense
r'Software\Microsoft\PolicyManager\default\WiFi\AllowWiFiHotSpotReporting': {
'DWORD Items': {'Value': 0},
},
r'Software\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots': {
'DWORD Items': {'Value': 0},
},
}
SETTINGS_EXPLORER_USER = {
# Disable silently installed apps
r'Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager': {
'DWORD Items': {'SilentInstalledAppsEnabled': 0},
},
# Disable Tips and Tricks
r'Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager': {
'DWORD Items': {'SoftLandingEnabled ': 0},
},
# 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': {
'DWORD Items': {'SearchboxTaskbarMode': 0},
},
# Change default Explorer view to "Computer"
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced': {
'DWORD Items': {'LaunchTo': 1},
},
}
SETTINGS_GOOGLE_CHROME = {
r'Software\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm': {
'SZ Items': {
'update_url': 'https://clients2.google.com/service/update2/crx'},
'WOW64_32': True,
},
r'Software\Google\Chrome\Extensions\pgdnlhfefecpicbbihgmbmffkjpaplco': {
'SZ Items': {
'update_url': 'https://clients2.google.com/service/update2/crx'},
'WOW64_32': True,
},
}
SETTINGS_MOZILLA_FIREFOX_32 = {
r'Software\Mozilla\Firefox\Extensions': {
'SZ Items': {
'uBlock0@raymondhill.net': MOZILLA_FIREFOX_UBO_PATH},
'WOW64_32': True,
},
}
SETTINGS_MOZILLA_FIREFOX_64 = {
r'Software\Mozilla\Firefox\Extensions': {
'SZ Items': {
'uBlock0@raymondhill.net': MOZILLA_FIREFOX_UBO_PATH},
},
}
VCR_REDISTS = [
{'Name': 'Visual C++ 2010 x32...',
'Cmd': [r'2010sp1\x32\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2010 x64...',
'Cmd': [r'2010sp1\x64\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2012 Update 4 x32...',
'Cmd': [r'2012u4\x32\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2012 Update 4 x64...',
'Cmd': [r'2012u4\x64\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2013 x32...',
'Cmd': [r'2013\x32\vcredist.exe', '/install',
'/passive', '/norestart']},
{'Name': 'Visual C++ 2013 x64...',
'Cmd': [r'2013\x64\vcredist.exe', '/install',
'/passive', '/norestart']},
{'Name': 'Visual C++ 2017 x32...',
'Cmd': [r'2017\x32\vcredist.exe', '/install',
'/passive', '/norestart']},
{'Name': 'Visual C++ 2017 x64...',
'Cmd': [r'2017\x64\vcredist.exe', '/install',
'/passive', '/norestart']},
]
# Configuration
def config_classicstart():
"""Configure ClassicStart."""
# User level, not system level
cs_exe = r'{PROGRAMFILES}\Classic Shell\ClassicStartMenu.exe'.format(
**global_vars['Env'])
skin = r'{PROGRAMFILES}\Classic Shell\Skins\Metro-Win10-Black.skin7'.format(
**global_vars['Env'])
extract_item('ClassicStartSkin', silent=True)
"""Configure ClassicStart."""
# User level, not system level
cs_exe = r'{PROGRAMFILES}\Classic Shell\ClassicStartMenu.exe'.format(
**global_vars['Env'])
skin = r'{PROGRAMFILES}\Classic Shell\Skins\Metro-Win10-Black.skin7'.format(
**global_vars['Env'])
extract_item('ClassicStartSkin', silent=True)
# Stop Classic Start
run_program([cs_exe, '-exit'], check=False)
sleep(1)
kill_process('ClassicStartMenu.exe')
# Stop Classic Start
run_program([cs_exe, '-exit'], check=False)
sleep(1)
kill_process('ClassicStartMenu.exe')
# Configure
write_registry_settings(SETTINGS_CLASSIC_START, all_users=False)
if global_vars['OS']['Version'] == '10' and os.path.exists(skin):
# Enable Win10 theme if on Win10
key_path = r'Software\IvoSoft\ClassicStartMenu\Settings'
with winreg.OpenKey(HKCU, key_path, access=winreg.KEY_WRITE) as key:
winreg.SetValueEx(
key, 'SkinW7', 0, winreg.REG_SZ, 'Metro-Win10-Black')
winreg.SetValueEx(key, 'SkinVariationW7', 0, winreg.REG_SZ, '')
# Configure
write_registry_settings(SETTINGS_CLASSIC_START, all_users=False)
if global_vars['OS']['Version'] == '10' and os.path.exists(skin):
# Enable Win10 theme if on Win10
key_path = r'Software\IvoSoft\ClassicStartMenu\Settings'
with winreg.OpenKey(HKCU, key_path, access=winreg.KEY_WRITE) as key:
winreg.SetValueEx(
key, 'SkinW7', 0, winreg.REG_SZ, 'Metro-Win10-Black')
winreg.SetValueEx(key, 'SkinVariationW7', 0, winreg.REG_SZ, '')
# Pin Browser to Start Menu (Classic)
firefox = r'{PROGRAMDATA}\Start Menu\Programs\Mozilla Firefox.lnk'.format(
**global_vars['Env'])
chrome = r'{PROGRAMDATA}\Start Menu\Programs\Google Chrome.lnk'.format(
**global_vars['Env'])
dest_path = r'{APPDATA}\ClassicShell\Pinned'.format(**global_vars['Env'])
source = None
dest = None
if os.path.exists(firefox):
source = firefox
dest = r'{}\Mozilla Firefox.lnk'.format(dest_path)
elif os.path.exists(chrome):
source = chrome
dest = r'{}\Google Chrome.lnk'.format(dest_path)
if source:
try:
os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest)
except Exception:
pass # Meh, it's fine without
# Pin Browser to Start Menu (Classic)
firefox = r'{PROGRAMDATA}\Start Menu\Programs\Mozilla Firefox.lnk'.format(
**global_vars['Env'])
chrome = r'{PROGRAMDATA}\Start Menu\Programs\Google Chrome.lnk'.format(
**global_vars['Env'])
dest_path = r'{APPDATA}\ClassicShell\Pinned'.format(**global_vars['Env'])
source = None
dest = None
if os.path.exists(firefox):
source = firefox
dest = r'{}\Mozilla Firefox.lnk'.format(dest_path)
elif os.path.exists(chrome):
source = chrome
dest = r'{}\Google Chrome.lnk'.format(dest_path)
if source:
try:
os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest)
except Exception:
pass # Meh, it's fine without
# (Re)start Classic Start
run_program([cs_exe, '-exit'], check=False)
sleep(1)
kill_process('ClassicStartMenu.exe')
sleep(1)
popen_program(cs_exe)
# (Re)start Classic Start
run_program([cs_exe, '-exit'], check=False)
sleep(1)
kill_process('ClassicStartMenu.exe')
sleep(1)
popen_program(cs_exe)
def config_explorer_system():
"""Configure Windows Explorer for all users via Registry settings."""
write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True)
"""Configure Windows Explorer for all users."""
write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True)
def config_explorer_user():
"""Configure Windows Explorer for current user 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 config_explorer_user(setup_mode='All'):
"""Configure Windows Explorer for current user per setup_mode."""
settings_explorer_user = {
k: v for k, v in SETTINGS_EXPLORER_USER.items()
if setup_mode not in v.get('Invalid modes', [])
}
write_registry_settings(settings_explorer_user, all_users=False)
def config_windows_updates():
"""Configure Windows updates."""
write_registry_settings(SETTINGS_WINDOWS_UPDATES, all_users=True)
def update_clock():
"""Set Timezone and sync clock."""
run_program(['tzutil' ,'/s', WINDOWS_TIME_ZONE], check=False)
run_program(['net', 'stop', 'w32ime'], check=False)
run_program(
['w32tm', '/config', '/syncfromflags:manual',
'/manualpeerlist:"us.pool.ntp.org time.nist.gov time.windows.com"',
],
check=False)
run_program(['net', 'start', 'w32ime'], check=False)
run_program(['w32tm', '/resync', '/nowait'], check=False)
"""Set Timezone and sync clock."""
run_program(['tzutil', '/s', WINDOWS_TIME_ZONE], check=False)
run_program(['net', 'stop', 'w32ime'], check=False)
run_program(
['w32tm', '/config', '/syncfromflags:manual',
'/manualpeerlist:"us.pool.ntp.org time.nist.gov time.windows.com"',
],
check=False)
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)
"""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)
# 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 find_current_software():
"""Find currently installed software, returns list."""
ninite_extras_path = r'{BaseDir}\Installers\Extras'.format(**global_vars)
installers = []
# Browsers
scan_for_browsers(silent=True)
for browser in ('Google Chrome', 'Mozilla Firefox', 'Opera Chromium'):
if is_installed(browser):
installers.append(
r'{}\Web Browsers\{}.exe'.format(ninite_extras_path, browser))
# TODO: Add more sections
return installers
def find_missing_software():
"""Find missing software based on dirs/files present, returns list."""
ninite_extras_path = r'{BaseDir}\Installers\Extras'.format(**global_vars)
installers = []
# Browsers
scan_for_browsers(silent=True)
for browser in ('Google Chrome', 'Mozilla Firefox', 'Opera Chromium'):
if profile_present(browser):
installers.append(
r'{}\Web Browsers\{}.exe'.format(ninite_extras_path, browser))
# TODO: Add more sections
return installers
def install_adobe_reader():
"""Install Adobe Reader."""
cmd = [
r'{BaseDir}\Installers\Extras\Office\Adobe Reader DC.exe'.format(
**global_vars),
'/sAll',
'/msi', '/norestart', '/quiet',
'ALLUSERS=1',
'EULA_ACCEPT=YES']
run_program(cmd)
"""Install Adobe Reader."""
cmd = [
r'{BaseDir}\Installers\Extras\Office\Adobe Reader DC.exe'.format(
**global_vars),
'/sAll',
'/msi', '/norestart', '/quiet',
'ALLUSERS=1',
'EULA_ACCEPT=YES']
run_program(cmd)
def install_chrome_extensions():
"""Update registry to install Google Chrome extensions for all users."""
write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True)
"""Install Google Chrome extensions for all users."""
write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True)
def install_classicstart_skin():
"""Extract ClassicStart skin to installation folder."""
if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
raise UnsupportedOSError
extract_item('ClassicStartSkin', silent=True)
source = r'{BinDir}\ClassicStartSkin\Metro-Win10-Black.skin7'.format(
**global_vars)
dest_path = r'{PROGRAMFILES}\Classic Shell\Skins'.format(
**global_vars['Env'])
dest = r'{}\Metro-Win10-Black.skin7'.format(dest_path)
os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest)
"""Extract ClassicStart skin to installation folder."""
if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
raise UnsupportedOSError
extract_item('ClassicStartSkin', silent=True)
source = r'{BinDir}\ClassicStartSkin\Metro-Win10-Black.skin7'.format(
**global_vars)
dest_path = r'{PROGRAMFILES}\Classic Shell\Skins'.format(
**global_vars['Env'])
dest = r'{}\Metro-Win10-Black.skin7'.format(dest_path)
os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest)
def install_firefox_extensions():
"""Update registry to install Firefox extensions for all users."""
dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format(
**global_vars['Env'])
source_path = r'{CBinDir}\FirefoxExtensions.7z'.format(**global_vars)
if not os.path.exists(source_path):
raise FileNotFoundError
"""Install Firefox extensions for all users."""
dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format(
**global_vars['Env'])
source_path = r'{CBinDir}\FirefoxExtensions.7z'.format(**global_vars)
if not os.path.exists(source_path):
raise FileNotFoundError
# Update registry
write_registry_settings(SETTINGS_MOZILLA_FIREFOX_32, all_users=True)
write_registry_settings(SETTINGS_MOZILLA_FIREFOX_64, all_users=True)
# 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',
'-p{ArchivePassword}'.format(**global_vars),
'-o{dist_path}'.format(dist_path=dist_path),
source_path]
run_program(cmd)
# Extract extension(s) to distribution folder
cmd = [
global_vars['Tools']['SevenZip'], 'e', '-aos', '-bso0', '-bse0',
'-p{ArchivePassword}'.format(**global_vars),
'-o{dist_path}'.format(dist_path=dist_path),
source_path]
run_program(cmd)
def install_ninite_bundle(mse=False):
"""Run Ninite file(s) based on OS version."""
def install_libreoffice(
quickstart=True, register_mso_types=True,
use_mso_formats=False, vcredist=False):
"""Install LibreOffice using specified settings."""
cmd = [
'msiexec', '/passive', '/norestart',
'/i', r'{}\Installers\Extras\Office\LibreOffice.msi'.format(
global_vars['BaseDir']),
'REBOOTYESNO=No',
'ISCHECKFORPRODUCTUPDATES=0',
'QUICKSTART={}'.format(1 if quickstart else 0),
'UI_LANGS=en_US',
'VC_REDIST={}'.format(1 if vcredist else 0),
]
if register_mso_types:
cmd.append('REGISTER_ALL_MSO_TYPES=1')
else:
cmd.append('REGISTER_NO_MSO_TYPES=1')
xcu_dir = r'{APPDATA}\LibreOffice\4\user'.format(**global_vars['Env'])
xcu_file = r'{}\registrymodifications.xcu'.format(xcu_dir)
# Set default save format
if use_mso_formats and not os.path.exists(xcu_file):
os.makedirs(xcu_dir, exist_ok=True)
with open(xcu_file, 'w', encoding='utf-8', newline='\n') as f:
f.write(LIBREOFFICE_XCU_DATA)
# Install LibreOffice
run_program(cmd, check=True)
def install_ninite_bundle(
# pylint: disable=too-many-arguments,too-many-branches
base=True,
browsers_only=False,
libreoffice=False,
missing=False,
mse=False,
standard=True,
):
"""Run Ninite installer(s), returns list of Popen objects."""
popen_objects = []
if browsers_only:
# This option is deprecated
installer_path = r'{BaseDir}\Installers\Extras\Web Browsers'.format(
**global_vars)
scan_for_browsers(silent=True)
for browser in ('Google Chrome', 'Mozilla Firefox', 'Opera Chromium'):
if is_installed(browser):
cmd = r'{}\{}.exe'.format(installer_path, browser)
popen_objects.append(popen_program(cmd))
# Bail
return popen_objects
# Main selections
main_selections = []
if base:
main_selections.append('base')
if standard:
if global_vars['OS']['Version'] in ('8', '8.1', '10'):
# Modern selection
popen_program(r'{BaseDir}\Installers\Extras\Bundles\Modern.exe'.format(
**global_vars))
main_selections.append('standard')
else:
# Legacy selection
if mse:
cmd = r'{BaseDir}\Installers\Extras\Security'.format(**global_vars)
cmd += r'\Microsoft Security Essentials.exe'
popen_program(cmd)
popen_program(r'{BaseDir}\Installers\Extras\Bundles\Legacy.exe'.format(
**global_vars))
main_selections.append('standard7')
if main_selections:
# Only run if base and/or standard are enabled
cmd = r'{}\Installers\Extras\Bundles\{}.exe'.format(
global_vars['BaseDir'],
'-'.join(main_selections),
)
popen_objects.append(popen_program([cmd]))
# Extra selections
extra_selections = {}
for cmd in find_current_software():
extra_selections[cmd] = True
if missing:
for cmd in find_missing_software():
extra_selections[cmd] = True
# Remove overlapping selections
regex = []
for n_name, n_group in NINITE_REGEX.items():
if n_name in main_selections:
regex.extend(n_group)
regex = '({})'.format('|'.join(regex))
extra_selections = {
cmd: True for cmd in extra_selections
if not re.search(regex, cmd, re.IGNORECASE)
}
# Start extra selections
for cmd in extra_selections:
popen_objects.append(popen_program([cmd]))
# Microsoft Security Essentials
if mse:
cmd = r'{}\Installers\Extras\Security\{}'.format(
global_vars['BaseDir'],
'Microsoft Security Essentials.exe',
)
popen_objects.append(popen_program([cmd]))
# LibreOffice
if libreoffice:
cmd = r'{}\Installers\Extras\Office\{}'.format(
global_vars['BaseDir'],
'LibreOffice.exe',
)
popen_objects.append(popen_program([cmd]))
# Done
return popen_objects
def install_vcredists():
"""Install all supported Visual C++ runtimes."""
extract_item('_vcredists', silent=True)
prev_dir = os.getcwd()
try:
os.chdir(r'{BinDir}\_vcredists'.format(**global_vars))
except FileNotFoundError:
# Ignored since the loop below will report the errors
pass
for vcr in VCR_REDISTS:
try_and_print(message=vcr['Name'], function=run_program,
cmd=vcr['Cmd'], other_results=OTHER_RESULTS)
"""Install all supported Visual C++ runtimes."""
extract_item('_vcredists', silent=True)
prev_dir = os.getcwd()
try:
os.chdir(r'{BinDir}\_vcredists'.format(**global_vars))
except FileNotFoundError:
# Ignored since the loop below will report the errors
pass
for vcr in VCR_REDISTS:
try_and_print(message=vcr['Name'], function=run_program,
cmd=vcr['Cmd'], other_results=OTHER_RESULTS)
os.chdir(prev_dir)
os.chdir(prev_dir)
# Misc
def open_device_manager():
popen_program(['mmc', 'devmgmt.msc'])
popen_program(['mmc', 'devmgmt.msc'])
def open_speedtest():
popen_program(['start', '', 'https://fast.com'], shell=True)
def open_windows_activation():
popen_program(['slui'])
popen_program(['slui'])
def open_windows_updates():
popen_program(['control', '/name', 'Microsoft.WindowsUpdate'])
popen_program(['control', '/name', 'Microsoft.WindowsUpdate'])
def restart_explorer():
"""Restart Explorer."""
kill_process('explorer.exe')
sleep(2)
kill_process('explorer.exe')
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,244 @@
# Wizard Kit: Functions - SW Diagnostics
import ctypes
from functions.common import *
from settings.sw_diags import *
def check_4k_alignment(show_alert=False):
"""Check that all partitions are 4K aligned."""
aligned = True
cmd = ['WMIC', 'partition', 'get', 'StartingOffset']
offsets = []
# Get offsets
result = run_program(cmd, encoding='utf-8', errors='ignore', check=False)
offsets = result.stdout.splitlines()
# Check offsets
for off in offsets:
off = off.strip()
if not off.isnumeric():
# Skip
continue
try:
aligned = aligned and int(off) % 4096 == 0
except ValueError:
# Ignore, this check is low priority
pass
# Show alert
if show_alert:
show_alert_box('One or more partitions are not 4K aligned')
raise Not4KAlignedError
def check_connection():
"""Check if the system is online and optionally abort the script."""
while True:
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_os_support_status():
"""Check if current OS is supported."""
msg = ''
outdated = False
unsupported = False
# Check OS version/notes
os_info = global_vars['OS'].copy()
if os_info['Notes'] == 'unsupported':
msg = 'The installed version of Windows is no longer supported'
unsupported = True
elif os_info['Notes'] == 'preview build':
msg = 'Preview builds are not officially supported'
unsupported = True
elif os_info['Version'] == '10' and os_info['Notes'] == 'outdated':
msg = 'The installed version of Windows is outdated'
outdated = True
if 'Preview' not in msg:
msg += '\n\nPlease consider upgrading before continuing setup.'
# Show alert
if outdated or unsupported:
show_alert_box(msg)
# Raise exception if necessary
if outdated:
raise WindowsOutdatedError
if unsupported:
raise WindowsUnsupportedError
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 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."""
extract_item('Autoruns', filter='autoruns*', silent=True)
# Update AutoRuns settings before running
for path, settings in AUTORUNS_SETTINGS.items():
winreg.CreateKey(HKCU, path)
with winreg.OpenKey(HKCU, path, access=winreg.KEY_WRITE) as key:
for name, value in settings.items():
winreg.SetValueEx(key, name, 0, winreg.REG_DWORD, value)
popen_program(global_vars['Tools']['AutoRuns'], minimized=True)
def run_hwinfo_sensors():
"""Run HWiNFO sensors."""
path = r'{BinDir}\HWiNFO'.format(**global_vars)
for bit in [32, 64]:
# Configure
source = r'{}\general.ini'.format(path)
dest = r'{}\HWiNFO{}.ini'.format(path, bit)
shutil.copy(source, dest)
with open(dest, 'a') as f:
f.write('SensorsOnly=1\n')
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():
"""Run HitmanPro in the background."""
extract_item('HitmanPro', silent=True)
cmd = [
global_vars['Tools']['HitmanPro'],
'/quiet', '/noinstall', '/noupload',
r'/log={LogDir}\Tools\HitmanPro.txt'.format(**global_vars)]
popen_program(cmd)
def run_process_killer():
"""Kill most running processes skipping those in the whitelist.txt."""
# borrowed from TronScript (reddit.com/r/TronScript)
# credit to /u/cuddlychops06
prev_dir = os.getcwd()
extract_item('ProcessKiller', silent=True)
os.chdir(r'{BinDir}\ProcessKiller'.format(**global_vars))
run_program(['ProcessKiller.exe', '/silent'], check=False)
os.chdir(prev_dir)
def run_rkill():
"""Run RKill and cleanup afterwards."""
extract_item('RKill', silent=True)
cmd = [
global_vars['Tools']['RKill'],
'-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')
# 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 = 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=None):
"""Show Windows alert box with message."""
if not title:
title = '{} Warning'.format(KIT_NAME_FULL)
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.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,47 @@
# Wizard Kit: Functions - Threading
from threading import Thread
from queue import Queue, Empty
# Classes
class NonBlockingStreamReader():
"""Class to allow non-blocking reads from a stream."""
# Credits:
## https://gist.github.com/EyalAr/7915597
## https://stackoverflow.com/a/4896288
def __init__(self, stream):
self.stream = stream
self.queue = Queue()
def populate_queue(stream, queue):
"""Collect lines from stream and put them in queue."""
while True:
line = stream.read(1)
if line:
queue.put(line)
self.thread = start_thread(
populate_queue,
args=(self.stream, self.queue))
def read(self, timeout=None):
try:
return self.queue.get(block = timeout is not None,
timeout = timeout)
except Empty:
return None
# Functions
def start_thread(function, args=[], daemon=True):
"""Run function as thread in background, returns Thread object."""
thread = Thread(target=function, args=args, daemon=daemon)
thread.start()
return thread
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,187 @@
# Wizard Kit: Functions - tmux
from functions.common import *
def create_file(filepath):
"""Create file if it doesn't exist."""
if not os.path.exists(filepath):
with open(filepath, 'w') as f:
f.write('')
def tmux_capture_pane(pane_id=None):
"""Capture text from target, or current, pane, returns str."""
cmd = ['tmux', 'capture-pane', '-p']
if pane_id:
cmd.extend(['-t', pane_id])
text = ''
# Capture
result = run_program(cmd, check=False, encoding='utf-8', errors='ignore')
text = result.stdout
# Done
return str(text)
def tmux_get_pane_size(pane_id=None):
"""Get target, or current, pane size, returns tuple."""
x = -1
y = -1
cmd = ['tmux', 'display', '-p']
if pane_id:
cmd.extend(['-t', pane_id])
cmd.append('#{pane_width} #{pane_height}')
# Run cmd and set x & y
result = run_program(cmd, check=False)
try:
x, y = result.stdout.decode().strip().split()
x = int(x)
y = int(y)
except Exception:
# Ignore and return unrealistic values
pass
return (x, y)
def tmux_kill_all_panes(pane_id=None):
"""Kill all tmux panes except the active pane or pane_id if specified."""
cmd = ['tmux', 'kill-pane', '-a']
if pane_id:
cmd.extend(['-t', pane_id])
run_program(cmd, check=False)
def tmux_kill_pane(*panes):
"""Kill tmux pane by id."""
cmd = ['tmux', 'kill-pane', '-t']
for pane_id in panes:
if not pane_id:
# Skip empty strings, None values, etc
continue
run_program(cmd+[pane_id], check=False)
def tmux_poll_pane(pane_id):
"""Check if pane exists, returns bool."""
cmd = ['tmux', 'list-panes', '-F', '#D']
result = run_program(cmd, check=False)
panes = result.stdout.decode().splitlines()
return pane_id in panes
def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs):
"""Resize pane to specific hieght or width."""
if not x and not y:
raise Exception('Neither height nor width specified.')
cmd = ['tmux', 'resize-pane']
if pane_id:
# NOTE: If pane_id not specified then the current pane will be resized
cmd.extend(['-t', pane_id])
if x:
cmd.extend(['-x', str(x)])
elif y:
cmd.extend(['-y', str(y)])
run_program(cmd, check=False)
def tmux_split_window(
lines=None, percent=None,
behind=False, vertical=False,
follow=False, target_pane=None,
command=None, working_dir=None,
text=None, watch=None, watch_cmd='cat'):
"""Run tmux split-window command and return pane_id as str."""
# Bail early
if not lines and not percent:
raise Exception('Neither lines nor percent specified.')
if not command and not text and not watch:
raise Exception('No command, text, or watch file specified.')
# Build cmd
cmd = ['tmux', 'split-window', '-PF', '#D']
if behind:
cmd.append('-b')
if vertical:
cmd.append('-v')
else:
cmd.append('-h')
if not follow:
cmd.append('-d')
if lines is not None:
cmd.extend(['-l', str(lines)])
elif percent is not None:
cmd.extend(['-p', str(percent)])
if target_pane:
cmd.extend(['-t', str(target_pane)])
if working_dir:
cmd.extend(['-c', working_dir])
if command:
cmd.extend(command)
elif text:
cmd.extend(['echo-and-hold "{}"'.format(text)])
elif watch:
create_file(watch)
if watch_cmd == 'cat':
cmd.extend([
'watch', '--color', '--no-title',
'--interval', '1',
'cat', watch])
elif watch_cmd == 'tail':
cmd.extend(['tail', '-f', watch])
# Run and return pane_id
result = run_program(cmd)
return result.stdout.decode().strip()
def tmux_switch_client(target_session=None):
"""Switch to target tmux session, or previous if none specified."""
cmd = ['tmux', 'switch-client']
if target_session:
cmd.extend(['-t', target_session])
else:
# Switch to previous instead
cmd.append('-p')
run_program(cmd, check=False)
def tmux_update_pane(
pane_id, command=None, working_dir=None,
text=None, watch=None, watch_cmd='cat'):
"""Respawn with either a new command or new text."""
# Bail early
if not command and not text and not watch:
raise Exception('No command, text, or watch file specified.')
cmd = ['tmux', 'respawn-pane', '-k', '-t', pane_id]
if working_dir:
cmd.extend(['-c', working_dir])
if command:
cmd.extend(command)
elif text:
cmd.extend(['echo-and-hold "{}"'.format(text)])
elif watch:
create_file(watch)
if watch_cmd == 'cat':
cmd.extend([
'watch', '--color', '--no-title',
'--interval', '1',
'cat', watch])
elif watch_cmd == 'tail':
cmd.extend(['tail', '-f', watch])
run_program(cmd)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,471 @@
"""Wizard Kit: Functions - UFD"""
# pylint: disable=broad-except,wildcard-import
# vim: sts=2 sw=2 ts=2
import os
import re
import shutil
import pathlib
from collections import OrderedDict
from functions.common import *
def case_insensitive_search(path, item):
"""Search path for item case insensitively, returns str."""
regex_match = '^{}$'.format(item)
real_path = ''
# Quick check first
if os.path.exists('{}/{}'.format(path, item)):
real_path = '{}{}{}'.format(
path,
'' if path == '/' else '/',
item,
)
# Check all items in dir
for entry in os.scandir(path):
if re.match(regex_match, entry.name, re.IGNORECASE):
real_path = '{}{}{}'.format(
path,
'' if path == '/' else '/',
entry.name,
)
# Done
if not real_path:
raise FileNotFoundError('{}/{}'.format(path, item))
return real_path
def confirm_selections(args):
"""Ask tech to confirm selections, twice if necessary."""
if not ask('Is the above information correct?'):
abort(False)
## Safety check
if not args['--update']:
print_standard(' ')
print_warning('SAFETY CHECK')
print_standard(
'All data will be DELETED from the disk and partition(s) listed above.')
print_standard(
'This is irreversible and will lead to {RED}DATA LOSS.{CLEAR}'.format(
**COLORS))
if not ask('Asking again to confirm, is this correct?'):
abort(False)
print_standard(' ')
def copy_source(source, items, overwrite=False):
"""Copy source items to /mnt/UFD."""
is_image = source.is_file()
# Mount source if necessary
if is_image:
mount(source, '/mnt/Source')
# Copy items
for i_source, i_dest in items:
i_source = '{}{}'.format(
'/mnt/Source' if is_image else source,
i_source,
)
i_dest = '/mnt/UFD{}'.format(i_dest)
try:
recursive_copy(i_source, i_dest, overwrite=overwrite)
except FileNotFoundError:
# Going to assume (hope) that this is fine
pass
# Unmount source if necessary
if is_image:
unmount('/mnt/Source')
def find_first_partition(dev_path):
"""Find path to first partition of dev, returns str."""
cmd = [
'lsblk',
'--list',
'--noheadings',
'--output', 'name',
'--paths',
dev_path,
]
result = run_program(cmd, encoding='utf-8', errors='ignore')
part_path = result.stdout.splitlines()[-1].strip()
return part_path
def find_path(path):
"""Find path case-insensitively, returns pathlib.Path obj."""
path_obj = pathlib.Path(path).resolve()
# Quick check first
if path_obj.exists():
return path_obj
# Fix case
parts = path_obj.relative_to('/').parts
real_path = '/'
for part in parts:
try:
real_path = case_insensitive_search(real_path, part)
except NotADirectoryError:
# Reclassify error
raise FileNotFoundError(path)
# Raise error if path doesn't exist
path_obj = pathlib.Path(real_path)
if not path_obj.exists():
raise FileNotFoundError(path_obj)
# Done
return path_obj
def get_user_home(user):
"""Get path to user's home dir, returns str."""
home_dir = None
cmd = ['getent', 'passwd', user]
result = run_program(cmd, encoding='utf-8', errors='ignore', check=False)
try:
home_dir = result.stdout.split(':')[5]
except Exception:
# Just use HOME from ENV (or '/root' if that fails)
home_dir = os.environ.get('HOME', '/root')
return home_dir
def get_user_name():
"""Get real user name, returns str."""
user = None
if 'SUDO_USER' in os.environ:
user = os.environ.get('SUDO_USER', 'Unknown')
else:
user = os.environ.get('USER', 'Unknown')
return user
def hide_items(ufd_dev, items):
"""Set FAT32 hidden flag for items."""
# pylint: disable=invalid-name
with open('/root/.mtoolsrc', 'w') as f:
f.write('drive U: file="{}"\n'.format(
find_first_partition(ufd_dev)))
f.write('mtools_skip_check=1\n')
# Hide items
for item in items:
cmd = ['yes | mattrib +h "U:/{}"'.format(item)]
run_program(cmd, check=False, shell=True)
def install_syslinux_to_dev(ufd_dev, use_mbr):
"""Install Syslinux to UFD (dev)."""
cmd = [
'dd',
'bs=440',
'count=1',
'if=/usr/lib/syslinux/bios/{}.bin'.format(
'mbr' if use_mbr else 'gptmbr',
),
'of={}'.format(ufd_dev),
]
run_program(cmd)
def install_syslinux_to_partition(partition):
"""Install Syslinux to UFD (partition)."""
cmd = [
'syslinux',
'--install',
'--directory',
'/arch/boot/syslinux/',
partition,
]
run_program(cmd)
def is_valid_path(path_obj, path_type):
"""Verify path_obj is valid by type, returns bool."""
valid_path = False
if path_type == 'DIR':
valid_path = path_obj.is_dir()
elif path_type == 'KIT':
valid_path = path_obj.is_dir() and path_obj.joinpath('.bin').exists()
elif path_type == 'IMG':
valid_path = path_obj.is_file() and path_obj.suffix.lower() == '.img'
elif path_type == 'ISO':
valid_path = path_obj.is_file() and path_obj.suffix.lower() == '.iso'
elif path_type == 'UFD':
valid_path = path_obj.is_block_device()
return valid_path
def mount(mount_source, mount_point, read_write=False):
"""Mount mount_source on mount_point."""
os.makedirs(mount_point, exist_ok=True)
cmd = [
'mount',
mount_source,
mount_point,
'-o',
'rw' if read_write else 'ro',
]
run_program(cmd)
def prep_device(dev_path, label, use_mbr=False, indent=2):
"""Format device in preparation for applying the WizardKit components
This is done is four steps:
1. Zero-out first 64MB (this deletes the partition table and/or bootloader)
2. Create a new partition table (GPT by default, optionally MBR)
3. Set boot flag
4. Format partition (FAT32, 4K aligned)
"""
# Zero-out first 64MB
cmd = 'dd bs=4M count=16 if=/dev/zero of={}'.format(dev_path).split()
try_and_print(
indent=indent,
message='Zeroing first 64MB...',
function=run_program,
cmd=cmd,
)
# Create partition table
cmd = 'parted {} --script -- mklabel {} mkpart primary fat32 4MiB {}'.format(
dev_path,
'msdos' if use_mbr else 'gpt',
'-1s' if use_mbr else '-4MiB',
).split()
try_and_print(
indent=indent,
message='Creating partition table...',
function=run_program,
cmd=cmd,
)
# Set boot flag
cmd = 'parted {} set 1 {} on'.format(
dev_path,
'boot' if use_mbr else 'legacy_boot',
).split()
try_and_print(
indent=indent,
message='Setting boot flag...',
function=run_program,
cmd=cmd,
)
# Format partition
cmd = [
'mkfs.vfat', '-F', '32',
'-n', label,
find_first_partition(dev_path),
]
try_and_print(
indent=indent,
message='Formatting partition...',
function=run_program,
cmd=cmd,
)
def recursive_copy(source, dest, overwrite=False):
"""Copy source to dest recursively.
NOTE: This uses rsync style source/dest syntax.
If the source has a trailing slash then it's contents are copied,
otherwise the source itself is copied.
Examples assuming "ExDir/ExFile.txt" exists:
recursive_copy("ExDir", "Dest/") results in "Dest/ExDir/ExFile.txt"
recursive_copy("ExDir/", "Dest/") results in "Dest/ExFile.txt"
NOTE 2: dest does not use find_path because it might not exist.
"""
copy_contents = source.endswith('/')
source = find_path(source)
dest = pathlib.Path(dest).resolve().joinpath(source.name)
os.makedirs(dest.parent, exist_ok=True)
if source.is_dir():
if copy_contents:
# Trailing slash syntax
for item in os.scandir(source):
recursive_copy(item.path, dest.parent, overwrite=overwrite)
elif not dest.exists():
# No conflict, copying whole tree (no merging needed)
shutil.copytree(source, dest)
elif not dest.is_dir():
# Refusing to replace file with dir
raise FileExistsError('Refusing to replace file: {}'.format(dest))
else:
# Dest exists and is a dir, merge dirs
for item in os.scandir(source):
recursive_copy(item.path, dest, overwrite=overwrite)
elif source.is_file():
if not dest.exists():
# No conflict, copying file
shutil.copy2(source, dest)
elif not dest.is_file():
# Refusing to replace dir with file
raise FileExistsError('Refusing to replace dir: {}'.format(dest))
elif overwrite:
# Dest file exists, deleting and replacing file
os.remove(dest)
shutil.copy2(source, dest)
else:
# Refusing to delete file when overwrite=False
raise FileExistsError('Refusing to delete file: {}'.format(dest))
def remove_arch():
"""Remove arch dir from UFD.
This ensures a clean installation to the UFD and resets the boot files
"""
shutil.rmtree(find_path('/mnt/UFD/arch'))
def running_as_root():
"""Check if running with effective UID of 0, returns bool."""
return os.geteuid() == 0
def show_selections(args, sources, ufd_dev, ufd_sources):
"""Show selections including non-specified options."""
# Sources
print_info('Sources')
for label in ufd_sources.keys():
if label in sources:
print_standard(' {label:<18} {path}'.format(
label=label+':',
path=sources[label],
))
else:
print_standard(' {label:<18} {YELLOW}Not Specified{CLEAR}'.format(
label=label+':',
**COLORS,
))
print_standard(' ')
# Destination
print_info('Destination')
cmd = [
'lsblk', '--nodeps', '--noheadings', '--paths',
'--output', 'NAME,FSTYPE,TRAN,SIZE,VENDOR,MODEL,SERIAL',
ufd_dev,
]
result = run_program(cmd, check=False, encoding='utf-8', errors='ignore')
print_standard(result.stdout.strip())
cmd = [
'lsblk', '--noheadings', '--paths',
'--output', 'NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT',
ufd_dev,
]
result = run_program(cmd, check=False, encoding='utf-8', errors='ignore')
for line in result.stdout.splitlines()[1:]:
print_standard(line)
# Notes
if args['--update']:
print_warning('Updating kit in-place')
elif args['--use-mbr']:
print_warning('Formatting using legacy MBR')
print_standard(' ')
def unmount(mount_point):
"""Unmount mount_point."""
cmd = ['umount', mount_point]
run_program(cmd)
def update_boot_entries(boot_entries, boot_files, iso_label, ufd_label):
"""Update boot files for UFD usage"""
configs = []
# Find config files
for c_path, c_ext in boot_files.items():
c_path = find_path('/mnt/UFD{}'.format(c_path))
for item in os.scandir(c_path):
if item.name.lower().endswith(c_ext.lower()):
configs.append(item.path)
# Update Linux labels
cmd = [
'sed',
'--in-place',
'--regexp-extended',
's/{}/{}/'.format(iso_label, ufd_label),
*configs,
]
run_program(cmd)
# Uncomment extra entries if present
for b_path, b_comment in boot_entries.items():
try:
find_path('/mnt/UFD{}'.format(b_path))
except (FileNotFoundError, NotADirectoryError):
# Entry not found, continue to next entry
continue
# Entry found, update config files
cmd = [
'sed',
'--in-place',
's/#{}#//'.format(b_comment),
*configs,
]
run_program(cmd, check=False)
def verify_sources(args, ufd_sources):
"""Check all sources and abort if necessary, returns dict."""
sources = OrderedDict()
for label, data in ufd_sources.items():
s_path = args[data['Arg']]
if s_path:
try:
s_path_obj = find_path(s_path)
except FileNotFoundError:
print_error('ERROR: {} not found: {}'.format(label, s_path))
abort(False)
if not is_valid_path(s_path_obj, data['Type']):
print_error('ERROR: Invalid {} source: {}'.format(label, s_path))
abort(False)
sources[label] = s_path_obj
return sources
def verify_ufd(dev_path):
"""Check that dev_path is a valid UFD, returns pathlib.Path obj."""
ufd_dev = None
try:
ufd_dev = find_path(dev_path)
except FileNotFoundError:
print_error('ERROR: UFD device not found: {}'.format(dev_path))
abort(False)
if not is_valid_path(ufd_dev, 'UFD'):
print_error('ERROR: Invalid UFD device: {}'.format(ufd_dev))
abort(False)
return ufd_dev
if __name__ == '__main__':
print("This file is not meant to be called directly.")

1502
.bin/Scripts/functions/update.py Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

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

View file

@ -0,0 +1,143 @@
# Wizard Kit: Functions - Windows updates
from functions.common import *
# Functions
def delete_folder(folder_path):
"""Near-useless wrapper for shutil.rmtree."""
shutil.rmtree(folder_path)
def disable_service(service_name):
"""Set service startup to disabled."""
run_program(['sc', 'config', service_name, 'start=', 'disabled'])
# Verify service was disabled
start_type = get_service_start_type(service_name)
if not start_type.lower().startswith('disabled'):
raise GenericError('Failed to disable service {}'.format(service_name))
def disable_windows_updates():
"""Disable windows updates and clear SoftwareDistribution folder."""
indent=2
width=52
update_folders = [
r'{WINDIR}\SoftwareDistribution'.format(**global_vars['Env']),
r'{SYSTEMDRIVE}\$WINDOWS.~BT'.format(**global_vars['Env']),
]
for service in ('wuauserv', 'bits'):
# Stop service
result = try_and_print(
'Stopping service {}...'.format(service),
indent=indent, width=width,
function=stop_service, service_name=service)
if not result['CS']:
result = try_and_print(
'Stopping service {}...'.format(service),
indent=indent, width=width,
function=stop_service, service_name=service)
if not result['CS']:
raise GenericError('Service {} could not be stopped.'.format(service))
# Disable service
result = try_and_print(
'Disabling service {}...'.format(service),
indent=indent, width=width,
function=disable_service, service_name=service)
if not result['CS']:
result = try_and_print(
'Disabling service {}...'.format(service),
indent=indent, width=width,
function=disable_service, service_name=service)
if not result['CS']:
raise GenericError('Service {} could not be disabled.'.format(service))
# Delete update folders
for folder_path in update_folders:
if os.path.exists(folder_path):
result = try_and_print(
'Deleting folder {}...'.format(folder_path),
indent=indent, width=width,
function=delete_folder, folder_path=folder_path)
if not result['CS']:
raise GenericError('Failed to remove folder {}'.format(folder_path))
def enable_service(service_name, start_type='auto'):
"""Enable service by setting start type."""
run_program(['sc', 'config', service_name, 'start=', start_type])
def enable_windows_updates(silent=False):
"""Enable windows updates"""
indent=2
width=52
for service in ('bits', 'wuauserv'):
# Enable service
start_type = 'auto'
if service == 'wuauserv':
start_type = 'demand'
if silent:
try:
enable_service(service, start_type=start_type)
except Exception:
# Try again
enable_service(service, start_type=start_type)
else:
result = try_and_print(
'Enabling service {}...'.format(service),
indent=indent, width=width,
function=enable_service, service_name=service, start_type=start_type)
if not result['CS']:
result = try_and_print(
'Enabling service {}...'.format(service),
indent=indent, width=width,
function=enable_service, service_name=service, start_type=start_type)
if not result['CS']:
raise GenericError('Service {} could not be enabled.'.format(service))
def get_service_status(service_name):
"""Get service status using psutil, returns str."""
status = 'Unknown'
try:
service = psutil.win_service_get(service_name)
status = service.status()
except psutil.NoSuchProcess:
# Ignore and return 'Unknown' below
pass
return status
def get_service_start_type(service_name):
"""Get service startup type using psutil, returns str."""
start_type = 'Unknown'
try:
service = psutil.win_service_get(service_name)
start_type = service.start_type()
except psutil.NoSuchProcess:
# Ignore and return 'Unknown' below
pass
return start_type
def stop_service(service_name):
"""Stop service."""
run_program(['net', 'stop', service_name], check=False)
# Verify service was stopped
status = get_service_status(service_name)
if not status.lower().startswith('stopped'):
raise GenericError('Failed to stop service {}'.format(service_name))
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -3,469 +3,433 @@
from functions.backup import *
from functions.disk import *
from functions.windows_setup import *
from settings.winpe import *
# STATIC VARIABLES
FAST_COPY_PE_ARGS = [
'/cmd=noexist_only',
'/utf8',
'/skip_empty_dir',
'/linkdest',
'/no_ui',
'/auto_close',
'/exclude={}'.format(';'.join(FAST_COPY_EXCLUDES)),
]
PE_TOOLS = {
'BlueScreenView': {
'Path': r'BlueScreenView\BlueScreenView.exe',
},
'FastCopy': {
'Path': r'FastCopy\FastCopy.exe',
'Args': FAST_COPY_PE_ARGS,
},
'HWiNFO': {
'Path': r'HWiNFO\HWiNFO.exe',
},
'NT Password Editor': {
'Path': r'NT Password Editor\ntpwedit.exe',
},
'Notepad++': {
'Path': r'NotepadPlusPlus\NotepadPlusPlus.exe',
},
'PhotoRec': {
'Path': r'TestDisk\photorec_win.exe',
'Args': ['-new_console:n'],
},
'Prime95': {
'Path': r'Prime95\prime95.exe',
},
'ProduKey': {
'Path': r'ProduKey\ProduKey.exe',
},
'Q-Dir': {
'Path': r'Q-Dir\Q-Dir.exe',
},
'TestDisk': {
'Path': r'TestDisk\testdisk_win.exe',
'Args': ['-new_console:n'],
},
}
def check_pe_tools():
"""Fix tool paths for WinPE layout."""
for k in PE_TOOLS.keys():
PE_TOOLS[k]['Path'] = r'{}\{}'.format(
global_vars['BinDir'], PE_TOOLS[k]['Path'])
global_vars['Tools']['wimlib-imagex'] = re.sub(
r'\\x(32|64)',
r'',
global_vars['Tools']['wimlib-imagex'],
re.IGNORECASE)
"""Fix tool paths for WinPE layout."""
for k in PE_TOOLS.keys():
PE_TOOLS[k]['Path'] = r'{}\{}'.format(
global_vars['BinDir'], PE_TOOLS[k]['Path'])
global_vars['Tools']['wimlib-imagex'] = re.sub(
r'\\x(32|64)',
r'',
global_vars['Tools']['wimlib-imagex'],
re.IGNORECASE)
def menu_backup():
"""Take backup images of partition(s) in the WIM format."""
errors = False
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'PathNotFoundError': 'Missing',
},
'Warning': {
'GenericAbort': 'Skipped',
'GenericRepair': 'Repaired',
}}
set_title('{}: Backup Menu'.format(KIT_NAME_FULL))
"""Take backup images of partition(s) in the WIM format."""
errors = False
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'PathNotFoundError': 'Missing',
},
'Warning': {
'GenericAbort': 'Skipped',
'GenericRepair': 'Repaired',
}}
set_title('{}: Backup Menu'.format(KIT_NAME_FULL))
# Set backup prefix
clear_screen()
print_standard('{}\n'.format(global_vars['Title']))
ticket_number = get_ticket_number()
if ENABLED_TICKET_NUMBERS:
backup_prefix = ticket_number
# Set backup prefix
clear_screen()
print_standard('{}\n'.format(global_vars['Title']))
ticket_number = get_ticket_number()
if ENABLED_TICKET_NUMBERS:
backup_prefix = ticket_number
else:
backup_prefix = get_simple_string(prompt='Enter backup name prefix')
backup_prefix = backup_prefix.replace(' ', '_')
# Assign drive letters
try_and_print(
message = 'Assigning letters...',
function = assign_volume_letters,
other_results = other_results)
# Mount backup shares
mount_backup_shares(read_write=True)
# Select destination
destination = select_backup_destination(auto_select=False)
# Scan disks
result = try_and_print(
message = 'Getting disk info...',
function = scan_disks,
other_results = other_results)
if result['CS']:
disks = result['Out']
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)
# Display details for backup task
clear_screen()
print_info('Create Backup - Details:\n')
if ENABLED_TICKET_NUMBERS:
show_data(message='Ticket:', data=ticket_number)
show_data(
message = 'Source:',
data = '[{}] ({}) {} {}'.format(
disk.get('Table', ''),
disk.get('Type', ''),
disk.get('Name', 'Unknown'),
disk.get('Size', ''),
),
)
show_data(
message = 'Destination:',
data = destination.get('Display Name', destination['Name']),
)
for par in disk['Partitions']:
message = 'Partition {}:'.format(par['Number'])
data = par['Display String']
if par['Number'] in disk['Bad Partitions']:
show_data(message=message, data=data, width=30, warning=True)
if 'Error' in par:
show_data(message='', data=par['Error'], error=True)
elif par['Image Exists']:
show_data(message=message, data=data, width=30, info=True)
else:
backup_prefix = get_simple_string(prompt='Enter backup name prefix')
backup_prefix = backup_prefix.replace(' ', '_')
show_data(message=message, data=data, width=30)
print_standard(disk['Backup Warnings'])
# Assign drive letters
try_and_print(
message = 'Assigning letters...',
function = assign_volume_letters,
other_results = other_results)
# Ask to proceed
if (not ask('Proceed with backup?')):
raise GenericAbort
# Mount backup shares
mount_backup_shares(read_write=True)
# Select destination
destination = select_backup_destination(auto_select=False)
# Scan disks
# Backup partition(s)
print_info('\n\nStarting task.\n')
for par in disk['Partitions']:
result = try_and_print(
message = 'Getting disk info...',
function = scan_disks,
other_results = other_results)
if result['CS']:
disks = result['Out']
else:
print_error('ERROR: No disks found.')
raise GenericAbort
message = 'Partition {} Backup...'.format(par['Number']),
function = backup_partition,
other_results = other_results,
disk = disk,
par = par)
if not result['CS'] and not isinstance(result['Error'], GenericAbort):
errors = True
par['Error'] = result['Error']
# 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)
# Display details for backup task
clear_screen()
print_info('Create Backup - Details:\n')
if ENABLED_TICKET_NUMBERS:
show_data(message='Ticket:', data=ticket_number)
show_data(
message = 'Source:',
data = '[{}] ({}) {} {}'.format(
disk.get('Table', ''),
disk.get('Type', ''),
disk.get('Name', 'Unknown'),
disk.get('Size', ''),
),
)
show_data(
message = 'Destination:',
data = destination.get('Display Name', destination['Name']),
)
# Verify backup(s)
if disk['Valid Partitions']:
print_info('\n\nVerifying backup images(s)\n')
for par in disk['Partitions']:
message = 'Partition {}:'.format(par['Number'])
data = par['Display String']
if par['Number'] in disk['Bad Partitions']:
show_data(message=message, data=data, width=30, warning=True)
if 'Error' in par:
show_data(message='', data=par['Error'], error=True)
elif par['Image Exists']:
show_data(message=message, data=data, width=30, info=True)
else:
show_data(message=message, data=data, width=30)
print_standard(disk['Backup Warnings'])
if par['Number'] in disk['Bad Partitions']:
continue # Skip verification
result = try_and_print(
message = 'Partition {} Image...'.format(par['Number']),
function = verify_wim_backup,
other_results = other_results,
partition = par)
if not result['CS']:
errors = True
par['Error'] = result['Error']
# 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']:
result = try_and_print(
message = 'Partition {} Backup...'.format(par['Number']),
function = backup_partition,
other_results = other_results,
disk = disk,
par = par)
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')
for par in disk['Partitions']:
if par['Number'] in disk['Bad Partitions']:
continue # Skip verification
result = try_and_print(
message = 'Partition {} Image...'.format(par['Number']),
function = verify_wim_backup,
other_results = other_results,
partition = par)
if not result['CS']:
errors = True
par['Error'] = result['Error']
# Print summary
if errors:
print_warning('\nErrors were encountered and are detailed below.')
for par in [p for p in disk['Partitions'] if 'Error' in p]:
print_standard(' Partition {} Error:'.format(par['Number']))
if hasattr(par['Error'], 'stderr'):
try:
par['Error'] = par['Error'].stderr.decode()
except:
# Deal with badly formatted error message
pass
try:
par['Error'] = par['Error'].splitlines()
par['Error'] = [line.strip() for line in par['Error']]
par['Error'] = [line for line in par['Error'] if line]
for line in par['Error']:
print_error('\t{}'.format(line))
except:
print_error('\t{}'.format(par['Error']))
else:
print_success('\nNo errors were encountered during imaging.')
if 'LogFile' in global_vars and ask('\nReview log?'):
cmd = [
global_vars['Tools']['NotepadPlusPlus'],
global_vars['LogFile']]
# Print summary
if errors:
print_warning('\nErrors were encountered and are detailed below.')
for par in [p for p in disk['Partitions'] if 'Error' in p]:
print_standard(' Partition {} Error:'.format(par['Number']))
if hasattr(par['Error'], 'stderr'):
try:
popen_program(cmd)
except Exception:
print_error('ERROR: Failed to open log.')
sleep(30)
pause('\nPress Enter to return to main menu... ')
par['Error'] = par['Error'].stderr.decode()
except:
# Deal with badly formatted error message
pass
try:
par['Error'] = par['Error'].splitlines()
par['Error'] = [line.strip() for line in par['Error']]
par['Error'] = [line for line in par['Error'] if line]
for line in par['Error']:
print_error('\t{}'.format(line))
except:
print_error('\t{}'.format(par['Error']))
else:
print_success('\nNo errors were encountered during imaging.')
if 'LogFile' in global_vars and ask('\nReview log?'):
cmd = [
global_vars['Tools']['NotepadPlusPlus'],
global_vars['LogFile']]
try:
popen_program(cmd)
except Exception:
print_error('ERROR: Failed to open log.')
sleep(30)
pause('\nPress Enter to return to main menu... ')
def menu_root():
"""Main WinPE menu."""
check_pe_tools()
menus = [
{'Name': 'Create Backups', 'Menu': menu_backup},
{'Name': 'Setup Windows', 'Menu': menu_setup},
{'Name': 'Misc Tools', 'Menu': menu_tools},
]
actions = [
{'Name': 'Command Prompt', 'Letter': 'C'},
{'Name': 'Reboot', 'Letter': 'R'},
{'Name': 'Shutdown', 'Letter': 'S'},
]
"""Main WinPE menu."""
check_pe_tools()
menus = [
{'Name': 'Create Backups', 'Menu': menu_backup},
{'Name': 'Setup Windows', 'Menu': menu_setup},
{'Name': 'Misc Tools', 'Menu': menu_tools},
]
actions = [
{'Name': 'Command Prompt', 'Letter': 'C'},
{'Name': 'Reboot', 'Letter': 'R'},
{'Name': 'Shutdown', 'Letter': 'S'},
]
# Main loop
while True:
set_title(KIT_NAME_FULL)
selection = menu_select(
title = 'Main Menu',
main_entries = menus,
action_entries = actions,
secret_exit = True)
# Main loop
while True:
set_title(KIT_NAME_FULL)
selection = menu_select(
title = 'Main Menu',
main_entries = menus,
action_entries = actions,
secret_exit = True)
if (selection.isnumeric()):
try:
menus[int(selection)-1]['Menu']()
except GenericAbort:
print_warning('\nAborted\n')
pause('Press Enter to return to main menu... ')
elif (selection == 'C'):
run_program(['cmd', '-new_console:n'], check=False)
elif (selection == 'R'):
run_program(['wpeutil', 'reboot'])
elif (selection == 'S'):
run_program(['wpeutil', 'shutdown'])
else:
sys.exit()
if (selection.isnumeric()):
try:
menus[int(selection)-1]['Menu']()
except GenericAbort:
print_warning('\nAborted\n')
pause('Press Enter to return to main menu... ')
elif (selection == 'C'):
run_program(['cmd', '-new_console:n'], check=False)
elif (selection == 'R'):
run_program(['wpeutil', 'reboot'])
elif (selection == 'S'):
run_program(['wpeutil', 'shutdown'])
else:
sys.exit()
def menu_setup():
"""Format a disk (MBR/GPT), apply a Windows image, and setup boot files."""
errors = False
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'PathNotFoundError': 'Missing',
},
'Warning': {
'GenericAbort': 'Skipped',
'GenericRepair': 'Repaired',
}}
set_title('{}: Setup Menu'.format(KIT_NAME_FULL))
"""Format a disk, apply a Windows image, and create boot files."""
errors = False
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'PathNotFoundError': 'Missing',
},
'Warning': {
'GenericAbort': 'Skipped',
'GenericRepair': 'Repaired',
}}
set_title('{}: Setup Menu'.format(KIT_NAME_FULL))
# Set ticket ID
clear_screen()
print_standard('{}\n'.format(global_vars['Title']))
ticket_number = get_ticket_number()
# Set ticket ID
clear_screen()
print_standard('{}\n'.format(global_vars['Title']))
ticket_number = get_ticket_number()
# Select the version of Windows to apply
windows_version = select_windows_version()
# 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(
message = 'Assigning volume letters...',
function = assign_volume_letters,
other_results = other_results)
windows_image = find_windows_image(windows_version)
# Find Windows image
# NOTE: Reassign volume letters to ensure all devices are scanned
try_and_print(
message = 'Assigning volume letters...',
function = assign_volume_letters,
other_results = other_results)
windows_image = find_windows_image(windows_version)
# Scan disks
result = try_and_print(
message = 'Getting disk info...',
function = scan_disks,
other_results = other_results)
if result['CS']:
disks = result['Out']
else:
print_error('ERROR: No disks found.')
raise GenericAbort
# Scan disks
result = try_and_print(
message = 'Getting disk info...',
function = scan_disks,
other_results = other_results)
if result['CS']:
disks = result['Out']
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
# 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)
# "Prep" disk
prep_disk_for_formatting(dest_disk)
# Display details for setup task
clear_screen()
print_info('Setup Windows - Details:\n')
if ENABLED_TICKET_NUMBERS:
show_data(message='Ticket:', data=ticket_number)
show_data(message='Installing:', data=windows_version['Name'])
# Display details for setup task
clear_screen()
print_info('Setup Windows - Details:\n')
if ENABLED_TICKET_NUMBERS:
show_data(message='Ticket:', data=ticket_number)
show_data(message='Installing:', data=windows_version['Name'])
show_data(
message = 'Boot Method:',
data = 'UEFI (GPT)' if dest_disk['Use GPT'] else 'Legacy (MBR)')
show_data(message='Using Image:', data=windows_image['Path'])
show_data(
message = 'ERASING:',
data = '[{}] ({}) {} {}\n'.format(
dest_disk.get('Table', ''),
dest_disk.get('Type', ''),
dest_disk.get('Name', 'Unknown'),
dest_disk.get('Size', ''),
),
warning = True)
for par in dest_disk['Partitions']:
show_data(
message = 'Boot Method:',
data = 'UEFI (GPT)' if dest_disk['Use GPT'] else 'Legacy (MBR)')
show_data(message='Using Image:', data=windows_image['Path'])
show_data(
message = 'ERASING:',
data = '[{}] ({}) {} {}\n'.format(
dest_disk.get('Table', ''),
dest_disk.get('Type', ''),
dest_disk.get('Name', 'Unknown'),
dest_disk.get('Size', ''),
),
warning = True)
for par in dest_disk['Partitions']:
show_data(
message = 'Partition {}:'.format(par['Number']),
data = par['Display String'],
warning = True)
print_warning(dest_disk['Format Warnings'])
message = 'Partition {}:'.format(par['Number']),
data = par['Display String'],
warning = True)
print_warning(dest_disk['Format Warnings'])
if (not ask('Is this correct?')):
raise GenericAbort
if (not ask('Is this correct?')):
raise GenericAbort
# Safety check
print_standard('\nSAFETY CHECK')
print_warning('All data will be DELETED from the '
'disk and partition(s) listed above.')
print_warning('This is irreversible and will lead '
'to {CLEAR}{RED}DATA LOSS.'.format(**COLORS))
if (not ask('Asking again to confirm, is this correct?')):
raise GenericAbort
# Safety check
print_standard('\nSAFETY CHECK')
print_warning('All data will be DELETED from the '
'disk and partition(s) listed above.')
print_warning('This is irreversible and will lead '
'to {CLEAR}{RED}DATA LOSS.'.format(**COLORS))
if (not ask('Asking again to confirm, is this correct?')):
raise GenericAbort
# Remove volume letters so S, T, & W can be used below
try_and_print(
message = 'Removing volume letters...',
function = remove_volume_letters,
other_results = other_results,
keep=windows_image['Letter'])
# Remove volume letters so S, T, & W can be used below
try_and_print(
message = 'Removing volume letters...',
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(
message = 'Reassigning source volume letter...',
function = reassign_volume_letter,
other_results = other_results,
letter=windows_image['Letter'])
windows_image['Path'] = '{}{}'.format(
new_letter, windows_image['Path'][1:])
windows_image['Letter'] = new_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(
message = 'Reassigning source volume letter...',
function = reassign_volume_letter,
other_results = other_results,
letter=windows_image['Letter'])
windows_image['Path'] = '{}{}'.format(
new_letter, windows_image['Path'][1:])
windows_image['Letter'] = new_letter
# Format and partition disk
result = try_and_print(
message = 'Formatting disk...',
function = format_disk,
other_results = other_results,
disk = dest_disk,
use_gpt = dest_disk['Use GPT'])
if not result['CS']:
# We need to crash as the disk is in an unknown state
print_error('ERROR: Failed to format disk.')
raise GenericAbort
# Format and partition disk
result = try_and_print(
message = 'Formatting disk...',
function = format_disk,
other_results = other_results,
disk = dest_disk,
use_gpt = dest_disk['Use GPT'])
if not result['CS']:
# We need to crash as the disk is in an unknown state
print_error('ERROR: Failed to format disk.')
raise GenericAbort
# Apply Image
result = try_and_print(
message = 'Applying image...',
function = setup_windows,
other_results = other_results,
windows_image = windows_image,
windows_version = windows_version)
if not result['CS']:
# We need to crash as the disk is in an unknown state
print_error('ERROR: Failed to apply image.')
raise GenericAbort
# Apply Image
result = try_and_print(
message = 'Applying image...',
function = setup_windows,
other_results = other_results,
windows_image = windows_image,
windows_version = windows_version)
if not result['CS']:
# 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)
# 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...',
function = setup_windows_re,
other_results = other_results,
windows_version = windows_version)
# Setup WinRE
try_and_print(
message = 'Updating recovery tools...',
function = setup_windows_re,
other_results = other_results,
windows_version = windows_version)
# Copy WinPE log(s)
source = r'{}\Logs'.format(global_vars['ClientDir'])
dest = r'W:\{}\Logs\WinPE'.format(KIT_NAME_SHORT)
shutil.copytree(source, dest)
# Copy WinPE log(s)
source = r'{}\Logs'.format(global_vars['ClientDir'])
dest = r'W:\{}\Logs\WinPE'.format(KIT_NAME_SHORT)
shutil.copytree(source, dest)
# Print summary
print_standard('\nDone.')
if 'LogFile' in global_vars and ask('\nReview log?'):
cmd = [
global_vars['Tools']['NotepadPlusPlus'],
global_vars['LogFile']]
try:
popen_program(cmd)
except Exception:
print_error('ERROR: Failed to open log.')
sleep(30)
pause('\nPress Enter to return to main menu... ')
# Print summary
print_standard('\nDone.')
if 'LogFile' in global_vars and ask('\nReview log?'):
cmd = [
global_vars['Tools']['NotepadPlusPlus'],
global_vars['LogFile']]
try:
popen_program(cmd)
except Exception:
print_error('ERROR: Failed to open log.')
sleep(30)
pause('\nPress Enter to return to main menu... ')
def menu_tools():
"""Tool launcher menu."""
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
actions = [{'Name': 'Main Menu', 'Letter': 'M'},]
set_title(KIT_NAME_FULL)
"""Tool launcher menu."""
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
actions = [{'Name': 'Main Menu', 'Letter': 'M'},]
set_title(KIT_NAME_FULL)
# Menu loop
while True:
selection = menu_select(
title = 'Tools Menu',
main_entries = tools,
action_entries = actions)
if (selection.isnumeric()):
name = tools[int(selection)-1]['Name']
cmd = [PE_TOOLS[name]['Path']] + PE_TOOLS[name].get('Args', [])
if name == 'Blue Screen View':
# Select path to scan
minidump_path = select_minidump_path()
if minidump_path:
cmd.extend(['/MiniDumpFolder', minidump_path])
try:
popen_program(cmd)
except Exception:
print_error('Failed to run {}'.format(name))
sleep(2)
pause()
elif (selection == 'M'):
break
# Menu loop
while True:
selection = menu_select(
title = 'Tools Menu',
main_entries = tools,
action_entries = actions)
if (selection.isnumeric()):
name = tools[int(selection)-1]['Name']
cmd = [PE_TOOLS[name]['Path']] + PE_TOOLS[name].get('Args', [])
if name == 'Blue Screen View':
# Select path to scan
minidump_path = select_minidump_path()
if minidump_path:
cmd.extend(['/MiniDumpFolder', minidump_path])
try:
popen_program(cmd)
except Exception:
print_error('Failed to run {}'.format(name))
sleep(2)
pause()
elif (selection == 'M'):
break
def select_minidump_path():
"""Select BSOD minidump path from a menu."""
dumps = []
"""Select BSOD minidump path from a menu."""
dumps = []
# Assign volume letters first
assign_volume_letters()
# Assign volume letters first
assign_volume_letters()
# Search for minidumps
set_thread_error_mode(silent=True) # Prevents "No disk" popups
for d in psutil.disk_partitions():
if global_vars['Env']['SYSTEMDRIVE'].upper() in d.mountpoint:
# Skip RAMDisk
continue
if os.path.exists(r'{}Windows\MiniDump'.format(d.mountpoint)):
dumps.append({'Name': r'{}Windows\MiniDump'.format(d.mountpoint)})
set_thread_error_mode(silent=False) # Return to normal
# Search for minidumps
set_thread_error_mode(silent=True) # Prevents "No disk" popups
for d in psutil.disk_partitions():
if global_vars['Env']['SYSTEMDRIVE'].upper() in d.mountpoint:
# Skip RAMDisk
continue
if os.path.exists(r'{}Windows\MiniDump'.format(d.mountpoint)):
dumps.append({'Name': r'{}Windows\MiniDump'.format(d.mountpoint)})
set_thread_error_mode(silent=False) # Return to normal
# Check results before showing menu
if len(dumps) == 0:
print_error('ERROR: No BSoD / MiniDump paths found')
sleep(2)
return None
# Check results before showing menu
if len(dumps) == 0:
print_error('ERROR: No BSoD / MiniDump paths found')
sleep(2)
return None
# Menu
selection = menu_select(
title = 'Which BSoD / MiniDump path are we scanning?',
main_entries = dumps)
return dumps[int(selection) - 1]['Name']
# Menu
selection = menu_select(
title = 'Which BSoD / MiniDump path are we scanning?',
main_entries = dumps)
return dumps[int(selection) - 1]['Name']
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,46 +1,11 @@
#!/bin/bash
#
## Wizard Kit: HW Diagnostics - Menu Launcher
## Wizard Kit: HW Diagnostics Launcher
source launch-in-tmux
SESSION_NAME="hw-diags"
WINDOW_NAME="Hardware Diagnostics"
MENU="hw-diags-menu"
function ask() {
while :; do
read -p "$1 [Y/N] " -r answer
if echo "$answer" | egrep -iq '^(y|yes|sure)$'; then
return 0
elif echo "$answer" | egrep -iq '^(n|no|nope)$'; then
return 1
fi
done
}
die () {
echo "$0:" "$@" >&2
exit 1
}
# Check for running session
if tmux list-session | grep -q "$SESSION_NAME"; then
echo "WARNING: tmux session $SESSION_NAME already exists."
echo ""
if ask "Connect to current session?"; then
# Do nothing, the command below will attach/connect
echo ""
elif ask "Kill current session and start new session?"; then
tmux kill-session -t "$SESSION_NAME" || \
die "Failed to kill session: $SESSION_NAME"
else
echo "Aborted."
echo ""
echo -n "Press Enter to exit... "
read -r
exit 0
fi
fi
# Start session
tmux new-session -A -s "$SESSION_NAME" -n "$WINDOW_NAME" "$MENU" $*
TMUX_CMD="hw-diags-menu"
launch_in_tmux "$@"

View file

@ -6,37 +6,37 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.common import *
init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
print_standard('Hardware Diagnostics: Audio\n')
# Set volume
try:
# Prep
clear_screen()
print_standard('Hardware Diagnostics: Audio\n')
run_program('amixer -q set "Master" 80% unmute'.split())
run_program('amixer -q set "PCM" 90% unmute'.split())
except subprocess.CalledProcessError:
print_error('Failed to set volume')
# Set volume
try:
run_program('amixer -q set "Master" 80% unmute'.split())
run_program('amixer -q set "PCM" 90% unmute'.split())
except subprocess.CalledProcessError:
print_error('Failed to set volume')
# Run tests
for mode in ['pink', 'wav']:
run_program(
cmd = 'speaker-test -c 2 -l 1 -t {}'.format(mode).split(),
check = False,
pipe = False)
# Done
#print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Run tests
for mode in ['pink', 'wav']:
run_program(
cmd = 'speaker-test -c 2 -l 1 -t {}'.format(mode).split(),
check = False,
pipe = False)
# Done
#print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -1,18 +0,0 @@
#!/bin/bash
#
## Wizard Kit: HW Diagnostics - badblocks
function usage {
echo "Usage: $0 device log-file"
echo " e.g. $0 /dev/sda /tmp/tmp.XXXXXXX/badblocks.log"
}
# Bail early
if [ ! -b "$1" ]; then
usage
exit 1
fi
# Run Badblocks
sudo badblocks -sv -e 1 "$1" 2>&1 | tee -a "$2"

View file

@ -6,25 +6,61 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.hw_diags import *
from functions.tmux import *
init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
# Show menu
try:
state = State()
menu_diags(state, sys.argv)
except KeyboardInterrupt:
print_standard(' ')
print_warning('Aborted')
print_standard(' ')
sleep(1)
pause('Press Enter to exit...')
except SystemExit as sys_exit:
tmux_switch_client()
exit_script(sys_exit.code)
except:
# Cleanup
tmux_kill_all_panes()
# Show menu
menu_diags(*sys.argv)
# Done
#print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
if DEBUG_MODE:
# Custom major exception
print_standard(' ')
print_error('Major exception')
print_warning(SUPPORT_MESSAGE)
print(traceback.format_exc())
print_log(traceback.format_exc())
# Save debug reports and upload data
try_and_print(
message='Saving debug reports...',
function=save_debug_reports,
state=state, global_vars=global_vars)
question = 'Upload crash details to {}?'.format(CRASH_SERVER['Name'])
if ENABLED_UPLOAD_DATA and ask(question):
try_and_print(
message='Uploading Data...',
function=upload_logdir,
global_vars=global_vars)
# Done
sleep(1)
pause('Press Enter to exit...')
exit_script(1)
else:
# "Normal" major exception
major_exception()
# Done
tmux_kill_all_panes()
tmux_switch_client()
exit_script()
# vim: sts=2 sw=2 ts=2

View file

@ -6,41 +6,43 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.network import *
def check_connection():
if not is_connected():
# Raise to cause NS in try_and_print()
raise Exception
if not is_connected():
# Raise to cause NS in try_and_print()
raise Exception
if __name__ == '__main__':
try:
# Prep
clear_screen()
print_standard('Hardware Diagnostics: Network\n')
try:
# Prep
clear_screen()
print_standard('Hardware Diagnostics: Network\n')
# Connect
print_standard('Initializing...')
connect_to_network()
# Connect
print_standard('Initializing...')
connect_to_network()
# Tests
try_and_print(
message='Network connection:', function=check_connection, cs='OK')
show_valid_addresses()
try_and_print(message='Internet connection:', function=ping,
addr='8.8.8.8', cs='OK')
try_and_print(message='DNS Resolution:', function=ping, cs='OK')
try_and_print(message='Speedtest:', function=speedtest,
print_return=True)
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Tests
try_and_print(
message='Network connection:', function=check_connection, cs='OK')
show_valid_addresses()
try_and_print(message='Internet connection:', function=ping,
addr='8.8.8.8', cs='OK')
try_and_print(message='DNS Resolution:', function=ping, cs='OK')
try_and_print(message='Speedtest:', function=speedtest,
print_return=True)
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -14,5 +14,6 @@ if [ ! -d "$1" ]; then
fi
# Run Prime95
mprime -t | grep -iv --line-buffered 'stress.txt' | tee -a "$1/prime.log"
cd "$1"
mprime -t | grep -iv --line-buffered 'stress.txt' | tee -a "prime.log"

View file

@ -3,9 +3,9 @@
BLUE='\033[34m'
CLEAR='\033[0m'
IFS=$'\n'
# List devices
IFS=$'\n'
for line in $(lsblk -do NAME,TRAN,SIZE,VENDOR,MODEL,SERIAL); do
if [[ "${line:0:4}" == "NAME" ]]; then
echo -e "${BLUE}${line}${CLEAR}"
@ -15,6 +15,18 @@ for line in $(lsblk -do NAME,TRAN,SIZE,VENDOR,MODEL,SERIAL); do
done
echo ""
# List loopback devices
if [[ "$(losetup -l | wc -l)" > 0 ]]; then
for line in $(losetup -lO NAME,PARTSCAN,RO,BACK-FILE); do
if [[ "${line:0:4}" == "NAME" ]]; then
echo -e "${BLUE}${line}${CLEAR}"
else
echo "${line}" | sed -r 's#/dev/(loop[0-9]+)#\1 #'
fi
done
echo ""
fi
# List partitions
for line in $(lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT); do
if [[ "${line:0:4}" == "NAME" ]]; then

View file

@ -105,8 +105,3 @@ echo -e "${BLUE}Drives${CLEAR}"
hw-drive-info | sed 's/^/ /'
echo ""
# Sensors
echo -e "${BLUE}Sensors${CLEAR}"
hw-sensors | sed 's/^/ /'
echo ""

View file

@ -1,168 +1,10 @@
#!/bin/python3
#!/bin/bash
#
## Wizard Kit: Sensor monitoring tool
import itertools
import os
import shutil
import sys
WINDOW_NAME="Hardware Sensors"
MONITOR="hw-sensors-monitor"
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.common import *
from borrowed import sensors
# STATIC VARIABLES
COLORS = {
'CLEAR': '\033[0m',
'RED': '\033[31m',
'GREEN': '\033[32m',
'YELLOW': '\033[33m',
'ORANGE': '\033[31;1m',
'BLUE': '\033[34m'
}
TEMP_LIMITS = {
'GREEN': 60,
'YELLOW': 70,
'ORANGE': 80,
'RED': 90,
}
# REGEX
REGEX_COLORS = re.compile(r'\033\[\d+;?1?m')
def color_temp(temp):
try:
temp = float(temp)
except ValueError:
return '{YELLOW}{temp}{CLEAR}'.format(temp=temp, **COLORS)
if temp > TEMP_LIMITS['RED']:
color = COLORS['RED']
elif temp > TEMP_LIMITS['ORANGE']:
color = COLORS['ORANGE']
elif temp > TEMP_LIMITS['YELLOW']:
color = COLORS['YELLOW']
elif temp > TEMP_LIMITS['GREEN']:
color = COLORS['GREEN']
elif temp > 0:
color = COLORS['BLUE']
else:
color = COLORS['CLEAR']
return '{color}{prefix}{temp:2.0f}°C{CLEAR}'.format(
color = color,
prefix = '-' if temp < 0 else '',
temp = temp,
**COLORS)
def get_feature_string(chip, feature):
sfs = list(sensors.SubFeatureIterator(chip, feature)) # get a list of all subfeatures
label = sensors.get_label(chip, feature)
skipname = len(feature.name)+1 # skip common prefix
data = {}
if feature.type != sensors.feature.TEMP:
# Skip non-temperature sensors
return None
for sf in sfs:
name = sf.name[skipname:].decode("utf-8").strip()
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
if '--nocolor' in sys.argv:
try:
temp = float(val)
except ValueError:
data[name] = ' {}°C'.format(val)
else:
data[name] = '{}{:2.0f}°C'.format(
'-' if temp < 0 else '',
temp)
else:
data[name] = color_temp(val)
main_temp = data.pop('input', None)
if main_temp:
list_data = []
for item in ['max', 'crit']:
if item in data:
list_data.append('{}: {}'.format(item, data.pop(item)))
list_data.extend(
['{}: {}'.format(k, v) for k, v in sorted(data.items())])
data_str = '{:18} {} {}'.format(
label, main_temp, ', '.join(list_data))
else:
list_data.extend(sorted(data.items()))
list_data = ['{}: {}'.format(item[0], item[1]) for item in list_data]
data_str = '{:18} {}'.format(label, ', '.join(list_data))
return data_str
def join_columns(column1, column2, width=55):
return '{:<{}}{}'.format(
column1,
55+len(column1)-len(REGEX_COLORS.sub('', column1)),
column2)
if __name__ == '__main__':
try:
# Prep
sensors.init()
# Get sensor data
chip_temps = {}
for chip in sensors.ChipIterator():
chip_name = '{} ({})'.format(
sensors.chip_snprintf_name(chip),
sensors.get_adapter_name(chip.bus))
chip_feats = [get_feature_string(chip, feature)
for feature in sensors.FeatureIterator(chip)]
# Strip empty/None items
chip_feats = [f for f in chip_feats if f]
if chip_feats:
chip_temps[chip_name] = [chip_name, *chip_feats, '']
# Sort chips
sensor_temps = []
for chip in [k for k in sorted(chip_temps.keys()) if 'coretemp' in k]:
sensor_temps.extend(chip_temps[chip])
for chip in sorted(chip_temps.keys()):
if 'coretemp' not in chip:
sensor_temps.extend(chip_temps[chip])
# Wrap columns as needed
screen_size = shutil.get_terminal_size()
rows = screen_size.lines - 1
if len(sensor_temps) > rows and screen_size.columns > 55*2:
sensor_temps = list(itertools.zip_longest(
sensor_temps[:rows], sensor_temps[rows:], fillvalue=''))
sensor_temps = [join_columns(a, b) for a, b in sensor_temps]
# Print data
if sensor_temps:
for line in sensor_temps:
print_standard(line)
else:
if '--nocolor' in sys.argv:
print_standard('WARNING: No sensors found')
print_standard('\nPlease monitor temps manually')
else:
print_warning('WARNING: No sensors found')
print_standard('\nPlease monitor temps manually')
# Done
sensors.cleanup()
exit_script()
except SystemExit:
sensors.cleanup()
pass
except:
sensors.cleanup()
major_exception()
# Start session
tmux new-session -n "$WINDOW_NAME" "$MONITOR"

36
.bin/Scripts/hw-sensors-monitor Executable file
View file

@ -0,0 +1,36 @@
#!/bin/python3
#
## Wizard Kit: Sensor monitoring tool
import os
import sys
# Init
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.sensors import *
from functions.tmux import *
init_global_vars(silent=True)
if __name__ == '__main__':
background = False
try:
if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
background = True
monitor_file = sys.argv[1]
monitor_pane = None
else:
result = run_program(['mktemp'])
monitor_file = result.stdout.decode().strip()
if not background:
monitor_pane = tmux_split_window(
percent=1, vertical=True, watch=monitor_file)
cmd = ['tmux', 'resize-pane', '-Z', '-t', monitor_pane]
run_program(cmd, check=False)
monitor_sensors(monitor_pane, monitor_file)
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,63 +4,60 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.setup import *
init_global_vars()
os.system('title {}: SW Bundle Tool'.format(KIT_NAME_FULL))
set_log_file('Install SW Bundle.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: SW Bundle Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
answer_extensions = ask('Install Extensions?')
answer_adobe_reader = ask('Install Adobe Reader?')
answer_vcr = ask('Install Visual C++ Runtimes?')
answer_ninite = ask('Install Ninite Bundle?')
if answer_ninite and global_vars['OS']['Version'] in ['7']:
# Vista is dead, not going to check for it
answer_mse = ask('Install MSE?')
else:
answer_mse = False
try:
stay_awake()
clear_screen()
print_info('{}: SW Bundle Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
answer_extensions = ask('Install Extensions?')
answer_vcr = ask('Install Visual C++ Runtimes?')
answer_ninite = ask('Install Ninite Bundle?')
if answer_ninite and global_vars['OS']['Version'] in ['7']:
# Vista is dead, not going to check for it
answer_mse = ask('Install MSE?')
else:
answer_mse = False
print_info('Installing Programs')
if answer_adobe_reader:
try_and_print(message='Adobe Reader DC...',
function=install_adobe_reader, other_results=other_results)
if answer_vcr:
install_vcredists()
if answer_ninite:
try_and_print(message='Ninite bundle...',
function=install_ninite_bundle, cs='Started',
mse=answer_mse, other_results=other_results)
if answer_extensions:
wait_for_process('ninite.exe')
print_info('Installing Extensions')
try_and_print(message='Classic Shell skin...',
function=install_classicstart_skin,
other_results=other_results)
try_and_print(message='Google Chrome extensions...',
function=install_chrome_extensions)
try_and_print(message='Mozilla Firefox extensions...',
function=install_firefox_extensions,
other_results=other_results)
print_standard('\nDone.')
exit_script()
except SystemExit:
pass
except:
major_exception()
print_info('Installing Programs')
if answer_vcr:
install_vcredists()
if answer_ninite:
result = try_and_print(message='Ninite bundle...',
function=install_ninite_bundle, cs='Started',
mse=answer_mse, other_results=other_results)
for proc in result['Out']:
# Wait for all processes to finish
proc.wait()
if answer_extensions:
print_info('Installing Extensions')
try_and_print(message='Classic Shell skin...',
function=install_classicstart_skin,
other_results=other_results)
try_and_print(message='Google Chrome extensions...',
function=install_chrome_extensions)
try_and_print(message='Mozilla Firefox extensions...',
function=install_firefox_extensions,
other_results=other_results)
print_standard('\nDone.')
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=4 sw=4 ts=4
# vim: sts=2 sw=2 ts=2

View file

@ -4,31 +4,32 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.setup import *
init_global_vars()
os.system('title {}: Install Visual C++ Runtimes'.format(KIT_NAME_FULL))
set_log_file('Install Visual C++ Runtimes.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: Install Visual C++ Runtimes\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
}}
try:
stay_awake()
clear_screen()
print_info('{}: Install Visual C++ Runtimes\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
}}
if ask('Install Visual C++ Runtimes?'):
install_vcredists()
else:
abort()
if ask('Install Visual C++ Runtimes?'):
install_vcredists()
else:
abort()
print_standard('\nDone.')
exit_script()
except SystemExit:
pass
except:
major_exception()
print_standard('\nDone.')
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

64
.bin/Scripts/launch-in-tmux Executable file
View file

@ -0,0 +1,64 @@
#!/bin/bash
#
## Wizard Kit: TMUX Launcher
function ask() {
while :; do
read -p "$1 [Y/N] " -r answer
if echo "$answer" | grep -Eiq '^(y|yes|sure)$'; then
return 0
elif echo "$answer" | grep -Eiq '^(n|no|nope)$'; then
return 1
fi
done
}
die () {
echo "$0:" "$@" >&2
exit 1
}
function launch_in_tmux() {
# Check for required vars
[[ -n "${SESSION_NAME:-}" ]] || die "Required variable missing (SESSION_NAME)"
[[ -n "${WINDOW_NAME:-}" ]] || die "Required variable missing (WINDOW_NAME)"
[[ -n "${TMUX_CMD:-}" ]] || die "Required variable missing (TMUX_CMD)"
# Check for running session
if tmux list-session | grep -q "$SESSION_NAME"; then
echo "WARNING: tmux session $SESSION_NAME already exists."
echo ""
if ask "Connect to current session?"; then
if [[ -n "${TMUX:-}" ]]; then
# Running inside TMUX, switch to session
tmux switch-client -t "$SESSION_NAME"
else
# Running outside TMUX, attach to session
tmux attach-session -t "$SESSION_NAME"
fi
exit 0
elif ask "Kill current session and start new session?"; then
tmux kill-session -t "$SESSION_NAME" || \
die "Failed to kill session: $SESSION_NAME"
else
echo "Aborted."
echo ""
echo -n "Press Enter to exit... "
read -r
exit 0
fi
fi
# Start/Rename session
if [[ -n "${TMUX:-}" ]]; then
# Running inside TMUX, rename session/window and open the menu
tmux rename-session "$SESSION_NAME"
tmux rename-window "$WINDOW_NAME"
"$TMUX_CMD" "$@"
tmux rename-session "${SESSION_NAME}_DONE"
tmux rename-window "${WINDOW_NAME}_DONE"
else
# Running outside TMUX, start/attach to session
tmux new-session -s "$SESSION_NAME" -n "$WINDOW_NAME" "$TMUX_CMD" "$@"
fi
}

View file

@ -6,33 +6,33 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.data import *
init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
print_standard('{}: Volume mount tool'.format(KIT_NAME_FULL))
try:
# Prep
clear_screen()
print_standard('{}: Volume mount tool'.format(KIT_NAME_FULL))
# Mount volumes
report = mount_volumes(all_devices=True)
# Mount volumes
report = mount_volumes(all_devices=True)
# Print report
print_info('\nResults')
for vol_name, vol_data in sorted(report.items()):
show_data(indent=4, width=20, **vol_data['show_data'])
# Print report
print_info('\nResults')
for vol_name, vol_data in sorted(report.items()):
show_data(indent=4, width=20, **vol_data['show_data'])
# Done
print_standard('\nDone.')
if 'gui' in sys.argv:
pause("Press Enter to exit...")
popen_program(['nohup', 'thunar', '/media'], pipe=True)
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
if 'gui' in sys.argv:
pause("Press Enter to exit...")
popen_program(['nohup', 'thunar', '/media'], pipe=True)
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -6,33 +6,30 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.data import *
from functions.network import *
init_global_vars()
if __name__ == '__main__':
try:
# Prep
clear_screen()
try:
# Prep
clear_screen()
# Connect
connect_to_network()
# Mount
if is_connected():
mount_backup_shares(read_write=True)
else:
# Couldn't connect
print_error('ERROR: No network connectivity.')
# Mount
if is_connected():
mount_backup_shares(read_write=True)
else:
# Couldn't connect
print_error('ERROR: No network connectivity.')
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -9,73 +9,76 @@ import sys
# STATIC VARIABLES
SCANDIR = os.getcwd()
USAGE = '''Usage: {script} <search-terms>...
e.g. {script} "Book Title" "Keyword" "etc"
e.g. {script} "Book Title" "Keyword" "etc"
This script will search all doc/docx files below the current directory for
the search-terms provided (case-insensitive).'''.format(script=__file__)
This script will search all doc/docx files below the current directory for
the search-terms provided (case-insensitive).'''.format(script=__file__)
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.network import *
init_global_vars()
REGEX_DOC_FILES = re.compile(r'\.docx?$', re.IGNORECASE)
def scan_for_docs(path):
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
yield from scantree(entry.path)
elif entry.is_file and REGEX_DOC_FILES.search(entry.name):
yield entry
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
yield from scan_for_docs(entry.path)
elif entry.is_file and REGEX_DOC_FILES.search(entry.name):
yield entry
def scan_file(file_path, search):
match = False
try:
if entry.name.lower().endswith('.docx'):
result = run_program(['unzip', '-p', entry.path])
else:
# Assuming .doc
result = run_program(['antiword', entry.path])
out = result.stdout.decode()
match = re.search(search, out, re.IGNORECASE)
except Exception:
# Ignore errors since files may be corrupted
pass
return entry.path if match else None
match = False
try:
if entry.name.lower().endswith('.docx'):
result = run_program(['unzip', '-p', entry.path])
else:
# Assuming .doc
result = run_program(['antiword', entry.path])
out = result.stdout.decode()
match = re.search(search, out, re.IGNORECASE)
except Exception:
# Ignore errors since files may be corrupted
pass
return entry.path if match else None
if __name__ == '__main__':
try:
# Prep
clear_screen()
terms = [re.sub(r'\s+', r'\s*', t) for t in sys.argv[1:]]
search = '({})'.format('|'.join(terms))
try:
# Prep
clear_screen()
terms = [re.sub(r'\s+', r'\s*', t) for t in sys.argv[1:]]
search = '({})'.format('|'.join(terms))
if len(sys.argv) == 1:
# Print usage
print_standard(USAGE)
else:
matches = []
for entry in scan_for_docs(SCANDIR):
matches.append(scan_file(entry.path, search))
# Strip None values (i.e. non-matching entries)
matches = [m for m in matches if m]
if matches:
print_success('Found {} {}:'.format(
len(matches),
'Matches' if len(matches) > 1 else 'Match'))
for match in matches:
print_standard(match)
else:
print_error('No matches found.')
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
if len(sys.argv) == 1:
# Print usage
print_standard(USAGE)
else:
matches = []
for entry in scan_for_docs(SCANDIR):
matches.append(scan_file(entry.path, search))
# Strip None values (i.e. non-matching entries)
matches = [m for m in matches if m]
if matches:
print_success('Found {} {}:'.format(
len(matches),
'Matches' if len(matches) > 1 else 'Match'))
for match in matches:
print_standard(match)
else:
print_error('No matches found.')
# Done
print_standard('\nDone.')
#pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,35 +4,36 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.safemode import *
init_global_vars()
os.system('title {}: SafeMode Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__':
try:
clear_screen()
print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}}
try:
clear_screen()
print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}}
if not ask('Enable booting to SafeMode (with Networking)?'):
abort()
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)
# 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...')
reboot()
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
pause('Press Enter to reboot...')
reboot()
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,35 +4,36 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.safemode import *
init_global_vars()
os.system('title {}: SafeMode Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__':
try:
clear_screen()
print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}}
try:
clear_screen()
print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}}
if not ask('Disable booting to SafeMode?'):
abort()
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)
# 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...')
reboot()
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
pause('Press Enter to reboot...')
reboot()
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,99 @@
# Wizard Kit: Settings - Browsers
import os
import re
# General
DEFAULT_HOMEPAGE = 'https://www.google.com/'
IE_GALLERY = 'https://www.microsoft.com/en-us/iegallery'
MOZILLA_PREFS = {
'browser.search.defaultenginename': '"Google"',
'browser.search.defaultenginename.US': '"Google"',
'browser.search.geoSpecificDefaults': 'false',
'browser.startup.homepage': '"{}"'.format(DEFAULT_HOMEPAGE),
'extensions.ui.lastCategory': '"addons://list/extension"',
}
SUPPORTED_BROWSERS = {
'Internet Explorer': {
'base': 'ie',
'exe_name': 'iexplore.exe',
'rel_install_path': 'Internet Explorer',
'user_data_path': r'{USERPROFILE}\Favorites',
},
'Google Chrome': {
'base': 'chromium',
'exe_name': 'chrome.exe',
'rel_install_path': r'Google\Chrome\Application',
'user_data_path': r'{LOCALAPPDATA}\Google\Chrome\User Data',
},
'Google Chrome Canary': {
'base': 'chromium',
'exe_name': 'chrome.exe',
'rel_install_path': r'Google\Chrome SxS\Application',
'user_data_path': r'{LOCALAPPDATA}\Google\Chrome SxS\User Data',
},
'Mozilla Firefox': {
'base': 'mozilla',
'exe_name': 'firefox.exe',
'rel_install_path': 'Mozilla Firefox',
'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles',
},
'Mozilla Firefox Dev': {
'base': 'mozilla',
'exe_name': 'firefox.exe',
'rel_install_path': 'Firefox Developer Edition',
'user_data_path': r'{APPDATA}\Mozilla\Firefox\Profiles',
},
'Opera': {
'base': 'chromium',
'exe_name': 'launcher.exe',
'rel_install_path': 'Opera',
'user_data_path': r'{APPDATA}\Opera Software\Opera Stable',
},
'Opera Beta': {
'base': 'chromium',
'exe_name': 'launcher.exe',
'rel_install_path': 'Opera beta',
'user_data_path': r'{APPDATA}\Opera Software\Opera Next',
},
'Opera Dev': {
'base': 'chromium',
'exe_name': 'launcher.exe',
'rel_install_path': 'Opera developer',
'user_data_path': r'{APPDATA}\Opera Software\Opera Developer',
},
}
# Regex
REGEX_BACKUP = re.compile(
r'\.\w*bak.*',
re.IGNORECASE)
REGEX_CHROMIUM_PROFILE = re.compile(
r'^(Default|Profile)',
re.IGNORECASE)
REGEX_CHROMIUM_ITEMS = re.compile(
r'^(Bookmarks|Cookies|Favicons|Google Profile'
r'|History|Login Data|Top Sites|TransportSecurity'
r'|Visited Links|Web Data)',
re.IGNORECASE)
REGEX_MOZILLA = re.compile(
r'^(bookmarkbackups|(cookies|formhistory|places).sqlite'
r'|key3.db|logins.json|persdict.dat)$',
re.IGNORECASE)
# uBlock Origin
UBO_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm?hl=en'
UBO_CHROME_REG = r'Software\Wow6432Node\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm'
UBO_EXTRA_CHROME = 'https://chrome.google.com/webstore/detail/ublock-origin-extra/pgdnlhfefecpicbbihgmbmffkjpaplco?hl=en'
UBO_EXTRA_CHROME_REG = r'Software\Wow6432Node\Google\Chrome\Extensions\pgdnlhfefecpicbbihgmbmffkjpaplco'
UBO_MOZILLA = 'https://addons.mozilla.org/en-us/firefox/addon/ublock-origin/'
UBO_MOZZILA_PATH = r'{}\Mozilla Firefox\distribution\extensions\ublock_origin.xpi'.format(os.environ.get('PROGRAMFILES'))
UBO_MOZILLA_REG = r'Software\Mozilla\Firefox\Extensions'
UBO_MOZILLA_REG_NAME = 'uBlock0@raymondhill.net'
UBO_OPERA = 'https://addons.opera.com/en/extensions/details/ublock/?display=en'
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2 tw=0

View file

@ -0,0 +1,37 @@
'''Wizard Kit: Settings - Cleanup'''
# vim: sts=2 sw=2 ts=2
import re
# Regex
DESKTOP_ITEMS = re.compile(
r'^(JRT|RKill|sc-cleaner)',
re.IGNORECASE,
)
# Registry
UAC_DEFAULTS_WIN7 = {
r'Software\Microsoft\Windows\CurrentVersion\Policies\System': {
'DWORD Items': {
'ConsentPromptBehaviorAdmin': 5,
'EnableLUA': 1,
'PromptOnSecureDesktop': 1,
},
},
}
UAC_DEFAULTS_WIN10 = {
r'Software\Microsoft\Windows\CurrentVersion\Policies\System': {
'DWORD Items': {
'ConsentPromptBehaviorAdmin': 5,
'ConsentPromptBehaviorUser': 3,
'EnableInstallerDetection': 1,
'EnableLUA': 1,
'EnableVirtualization': 1,
'PromptOnSecureDesktop': 1,
},
},
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")

View file

@ -0,0 +1,105 @@
# Wizard Kit: Settings - Data
import ctypes
import re
from settings.main import *
# FastCopy
FAST_COPY_EXCLUDES = [
r'\*.esd',
r'\*.swm',
r'\*.wim',
r'\*.dd',
r'\*.dd.tgz',
r'\*.dd.txz',
r'\*.map',
r'\*.dmg',
r'\*.image',
r'$RECYCLE.BIN',
r'$Recycle.Bin',
r'.AppleDB',
r'.AppleDesktop',
r'.AppleDouble',
r'.com.apple.timemachine.supported',
r'.dbfseventsd',
r'.DocumentRevisions-V100*',
r'.DS_Store',
r'.fseventsd',
r'.PKInstallSandboxManager',
r'.Spotlight*',
r'.SymAV*',
r'.symSchedScanLockxz',
r'.TemporaryItems',
r'.Trash*',
r'.vol',
r'.VolumeIcon.icns',
r'desktop.ini',
r'Desktop?DB',
r'Desktop?DF',
r'hiberfil.sys',
r'lost+found',
r'Network?Trash?Folder',
r'pagefile.sys',
r'Recycled',
r'RECYCLER',
r'System?Volume?Information',
r'Temporary?Items',
r'Thumbs.db',
]
FAST_COPY_ARGS = [
'/cmd=noexist_only',
'/utf8',
'/skip_empty_dir',
'/linkdest',
'/no_ui',
'/auto_close',
'/exclude={}'.format(';'.join(FAST_COPY_EXCLUDES)),
]
# Regex
REGEX_EXCL_ITEMS = re.compile(
r'^(\.(AppleDB|AppleDesktop|AppleDouble'
r'|com\.apple\.timemachine\.supported|dbfseventsd'
r'|DocumentRevisions-V100.*|DS_Store|fseventsd|PKInstallSandboxManager'
r'|Spotlight.*|SymAV.*|symSchedScanLockxz|TemporaryItems|Trash.*'
r'|vol|VolumeIcon\.icns)|desktop\.(ini|.*DB|.*DF)'
r'|(hiberfil|pagefile)\.sys|lost\+found|Network\.*Trash\.*Folder'
r'|Recycle[dr]|System\.*Volume\.*Information|Temporary\.*Items'
r'|Thumbs\.db)$',
re.IGNORECASE)
REGEX_EXCL_ROOT_ITEMS = re.compile(
r'^(boot(mgr|nxt)$|Config.msi'
r'|(eula|globdata|install|vc_?red)'
r'|.*.sys$|System Volume Information|RECYCLER?|\$Recycle\.bin'
r'|\$?Win(dows(.old.*|\. BT|)$|RE_)|\$GetCurrent|Windows10Upgrade'
r'|PerfLogs|Program Files|SYSTEM.SAV'
r'|.*\.(esd|swm|wim|dd|map|dmg|image)$)',
re.IGNORECASE)
REGEX_INCL_ROOT_ITEMS = re.compile(
r'^(AdwCleaner|(My\s*|)(Doc(uments?( and Settings|)|s?)|Downloads'
r'|Media|Music|Pic(ture|)s?|Vid(eo|)s?)'
r'|{prefix}(-?Info|-?Transfer|)'
r'|(ProgramData|Recovery|Temp.*|Users)$'
r'|.*\.(log|txt|rtf|qb\w*|avi|m4a|m4v|mp4|mkv|jpg|png|tiff?)$)'
r''.format(prefix=KIT_NAME_SHORT),
re.IGNORECASE)
REGEX_WIM_FILE = re.compile(
r'\.wim$',
re.IGNORECASE)
REGEX_WINDOWS_OLD = re.compile(
r'^Win(dows|)\.old',
re.IGNORECASE)
# Thread error modes
## Code borrowed from: https://stackoverflow.com/a/29075319
SEM_NORMAL = ctypes.c_uint()
SEM_FAILCRITICALERRORS = 1
SEM_NOOPENFILEERRORBOX = 0x8000
SEM_FAIL = SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,61 @@
# Wizard Kit: Settings - ddrescue-tui
import re
from collections import OrderedDict
# General
MAP_DIR = '/Backups/ddrescue-tui'
RECOMMENDED_FSTYPES = ['ext3', 'ext4', 'xfs']
RECOMMENDED_MAP_FSTYPES = ['cifs', 'ext2', 'ext3', 'ext4', 'vfat', 'xfs']
USAGE = """ {script_name} clone [source [destination]]
{script_name} image [source [destination]]
(e.g. {script_name} clone /dev/sda /dev/sdb)
"""
# Layout
SIDE_PANE_WIDTH = 21
TMUX_LAYOUT = OrderedDict({
'Source': {'y': 2, 'Check': True},
'Started': {'x': SIDE_PANE_WIDTH, 'Check': True},
'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True},
})
# ddrescue
AUTO_PASS_1_THRESHOLD = 95
AUTO_PASS_2_THRESHOLD = 98
DDRESCUE_SETTINGS = {
'--binary-prefixes': {'Enabled': True, 'Hidden': True, },
'--data-preview': {'Enabled': True, 'Value': '5', 'Hidden': True, },
'--idirect': {'Enabled': True, },
'--odirect': {'Enabled': True, },
'--max-read-rate': {'Enabled': False, 'Value': '1MiB', },
'--min-read-rate': {'Enabled': True, 'Value': '64KiB', },
'--reopen-on-error': {'Enabled': True, },
'--retry-passes': {'Enabled': True, 'Value': '0', },
'--test-mode': {'Enabled': False, 'Value': 'test.map', },
'--timeout': {'Enabled': True, 'Value': '5m', },
'-vvvv': {'Enabled': True, 'Hidden': True, },
}
ETOC_REFRESH_RATE = 30 # in seconds
REGEX_DDRESCUE_LOG = re.compile(
r'^\s*(?P<key>\S+):\s+'
r'(?P<size>\d+)\s+'
r'(?P<unit>[PTGMKB])i?B?',
re.IGNORECASE,
)
REGEX_REMAINING_TIME = re.compile(
r'remaining time:'
r'\s*((?P<days>\d+)d)?'
r'\s*((?P<hours>\d+)h)?'
r'\s*((?P<minutes>\d+)m)?'
r'\s*((?P<seconds>\d+)s)?'
r'\s*(?P<na>n/a)?',
re.IGNORECASE
)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,112 @@
# Wizard Kit: Settings - HW Diagnostics
from collections import OrderedDict
# General
DEBUG_MODE = False
OVERRIDES_FORCED = False
OVERRIDES_LIMITED = True # If True this disables OVERRIDE_FORCED
STATUSES = {
'RED': ['Denied', 'ERROR', 'NS', 'TimedOut'],
'YELLOW': ['Aborted', 'N/A', 'OVERRIDE', 'Unknown', 'Working'],
'GREEN': ['CS'],
}
TESTS_CPU = ['Prime95']
TESTS_DISK = [
'I/O Benchmark',
'NVMe / SMART',
'badblocks',
]
# Layout
## NOTE: Colors will be applied in functions/hw_diags.py
QUICK_LABEL = '{YELLOW}(Quick){CLEAR}'
SIDE_PANE_WIDTH = 20
TOP_PANE_TEXT = '{GREEN}Hardware Diagnostics{CLEAR}'
TMUX_LAYOUT = OrderedDict({
'Top': {'y': 2, 'Check': True},
'Started': {'x': SIDE_PANE_WIDTH, 'Check': True},
'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True},
# Testing panes
'Prime95': {'y': 11, 'Check': False},
'Temps': {'y': 1000, 'Check': False},
'SMART': {'y': 3, 'Check': True},
'badblocks': {'y': 5, 'Check': True},
'I/O Benchmark': {'y': 1000, 'Check': False},
})
# Tests: badblocks
## NOTE: Force 4K read block size for disks >= to 3TB
BADBLOCKS_LARGE_DISK = 3*1024**4
# Tests: I/O Benchmark
IO_VARS = {
'Block Size': 512*1024,
'Chunk Size': 32*1024**2,
'Minimum Test Size': 10*1024**3,
'Alt Test Size Factor': 0.01,
'Progress Refresh Rate': 5,
'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': (
'', '', '', '',
'', '', '', '',
'█▏', '█▎', '█▍', '█▌',
'█▋', '█▊', '█▉', '██',
'██▏', '██▎', '██▍', '██▌',
'██▋', '██▊', '██▉', '███',
'███▏', '███▎', '███▍', '███▌',
'███▋', '███▊', '███▉', '████'),
}
# Tests: NVMe/SMART
ATTRIBUTES = {
'NVMe': {
'critical_warning': {'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
'media_errors': {'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
'power_on_hours': {'Critical': False, 'Ignore': True, 'Warning': 17532, 'Error': 26298, 'Maximum': None, },
'unsafe_shutdowns': {'Critical': False, 'Ignore': True, 'Warning': 1, 'Error': None, 'Maximum': None, },
},
'SMART': {
5: {'Hex': '05', 'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
9: {'Hex': '09', 'Critical': False, 'Ignore': True, 'Warning': 17532, 'Error': 26298, 'Maximum': None, },
10: {'Hex': '10', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
184: {'Hex': 'B8', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
187: {'Hex': 'BB', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
188: {'Hex': 'BC', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
196: {'Hex': 'C4', 'Critical': False, 'Ignore': False, 'Warning': 1, 'Error': 10, 'Maximum': 10000, },
197: {'Hex': 'C5', 'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
198: {'Hex': 'C6', 'Critical': True, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': None, },
199: {'Hex': 'C7', 'Critical': False, 'Ignore': True, 'Warning': None, 'Error': 1, 'Maximum': None, },
201: {'Hex': 'C9', 'Critical': False, 'Ignore': False, 'Warning': None, 'Error': 1, 'Maximum': 10000, },
},
}
ATTRIBUTE_COLORS = (
('Error', 'RED'),
('Maximum', 'PURPLE'),
('Warning', 'YELLOW'),
)
KEY_NVME = 'nvme_smart_health_information_log'
KEY_SMART = 'ata_smart_attributes'
# Tests: Prime95
MPRIME_LIMIT = 7 # of minutes to run Prime95
THERMAL_LIMIT = 95 # Abort temperature in Celsius
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2 tw=0

View file

@ -0,0 +1,58 @@
# Wizard Kit: Settings - Information
import re
# General
REG_PROFILE_LIST = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
REG_SHELL_FOLDERS = r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
TMP_HIVE_PATH = 'TEMP_HIVE_MOUNT'
EXTRA_FOLDERS = [
'Dropbox',
'Google Drive',
'OneDrive',
'SkyDrive',
]
SHELL_FOLDERS = {
#GUIDs from: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
'Desktop': (
'{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}',
),
'Documents': (
'Personal',
'{FDD39AD0-238F-46AF-ADB4-6C85480369C7}',
),
'Downloads': (
'{374DE290-123F-4565-9164-39C4925E467B}',
),
'Favorites': (
'{1777F761-68AD-4D8A-87BD-30B759FA33DD}',
),
'Music': (
'My Music',
'{4BD8D571-6D19-48D3-BE97-422220080E43}',
),
'Pictures': (
'My Pictures',
'{33E28130-4E1E-4676-835A-98395C3BC3BB}',
),
'Videos': (
'My Video',
'{18989B1D-99B5-455B-841C-AB7C74E4DDFC}',
),
}
# Regex
REGEX_OFFICE = re.compile(
r'(Microsoft (Office\s+'
r'(365|Enterprise|Home|Pro(\s|fessional)'
r'|Single|Small|Standard|Starter|Ultimate|system)'
r'|Works[-\s\d]+\d)'
r'|(Libre|Open|Star)\s*Office'
r'|WordPerfect|Gnumeric|Abiword)',
re.IGNORECASE)
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

File diff suppressed because it is too large Load diff

View file

@ -13,79 +13,78 @@ KIT_NAME_FULL='WizardKit'
KIT_NAME_SHORT='WK'
SUPPORT_MESSAGE='Please let 2Shirt know by opening an issue on GitHub'
# Live Linux
MPRIME_LIMIT='7' # of minutes to run Prime95 during hw-diags
ROOT_PASSWORD='Abracadabra'
TECH_PASSWORD='Abracadabra'
# Server IP addresses
OFFICE_SERVER_IP='10.0.0.10'
QUICKBOOKS_SERVER_IP='10.0.0.10'
# Time Zones
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_PASSWORD='Abracadabra'
LINUX_TIME_ZONE='America/Denver' # See 'timedatectl list-timezones' for valid values
WINDOWS_TIME_ZONE='Mountain Standard Time' # See 'tzutil /l' for valid values
# SERVER VARIABLES
## NOTE: Windows can only use one user per server. This means that if
## one server serves multiple shares then you have to use the same
## user/password for all of those shares.
BACKUP_SERVERS = [
{ 'IP': '10.0.0.10',
'Name': 'ServerOne',
'Mounted': False,
'Share': 'Backups',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
{ 'IP': '10.0.0.10',
'Name': 'ServerOne',
'Mounted': False,
'Share': 'Backups',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
},
{ 'IP': '10.0.0.11',
'Name': 'ServerTwo',
'Mounted': False,
'Share': 'Backups',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
{ 'IP': '10.0.0.11',
'Name': 'ServerTwo',
'Mounted': False,
'Share': 'Backups',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
},
]
]
CRASH_SERVER = {
'Name': 'CrashServer',
'Url': '',
'User': '',
'Pass': '',
}
'Name': 'CrashServer',
'Url': '',
'User': '',
'Pass': '',
}
OFFICE_SERVER = {
'IP': OFFICE_SERVER_IP,
'Name': 'ServerOne',
'Mounted': False,
'Share': 'Office',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
}
'IP': OFFICE_SERVER_IP,
'Name': 'ServerOne',
'Mounted': False,
'Share': 'Office',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
}
QUICKBOOKS_SERVER = {
'IP': QUICKBOOKS_SERVER_IP,
'Name': 'ServerOne',
'Mounted': False,
'Share': 'QuickBooks',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
}
'IP': QUICKBOOKS_SERVER_IP,
'Name': 'ServerOne',
'Mounted': False,
'Share': 'QuickBooks',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
}
WINDOWS_SERVER = {
'IP': '10.0.0.10',
'Name': 'ServerOne',
'Mounted': False,
'Share': 'Windows',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
}
'IP': '10.0.0.10',
'Name': 'ServerOne',
'Mounted': False,
'Share': 'Windows',
'User': 'restore',
'Pass': 'Abracadabra',
'RW-User': 'backup',
'RW-Pass': 'Abracadabra',
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,70 +1,73 @@
# Wizard Kit: Settings - Music
MUSIC_MOD = [
'104208#banana_boat.mod',
'114971#tilbury_fair.mod',
'132563#ufo_tune.mod',
'135906#magnetik_girl.xm',
'140628#autumn_in_budapest.xm',
'143198#summer_memories_3.xm',
'144405#hillbilly_billyboy.xm',
'154795#4mat_-_eternity.xm',
'155845#bookworm.mo3',
'155914#battleofsteel.xm',
'158975#1_channel_moog.it',
'165495#trans.s3m',
'168513#necros_-_introspection.s3m',
'169628#radix_-_feng_shui_schematics.xm',
'175238#unknown48_-_twilight.mod',
'33432#ambrozia.xm',
'33460#amigatre.mod',
'34594#CHARIOT.S3M',
'34596#BUTTERFL.XM',
'34654#CTGOBLIN.S3M',
'35151#bananasplit.mod',
'35280#DEADLOCK.XM',
'38591#compo_liam.xm',
'39987#crystald.s3m',
'40475#ELYSIUM.MOD',
'42146#enigma.mod',
'42519#GHOST2.MOD',
'42560#GSLINGER.MOD',
'42872#existing.xm',
'50427#nf-stven.xm',
'51549#overture.mod',
'54250#SATELL.S3M',
'54313#realmk.s3m',
'55789#scrambld.mod',
'57934#spacedeb.mod',
'59344#stardstm.mod',
'60395#2ND_PM.S3M',
'66187#external.xm',
'66343#beek-substitutionology.it',
'67561#radix-unreal_superhero.xm',
'70829#inside_out.s3m',
'83779#beyond_music.mod',
]
'104208#banana_boat.mod',
'114971#tilbury_fair.mod',
'132563#ufo_tune.mod',
'135906#magnetik_girl.xm',
'140628#autumn_in_budapest.xm',
'143198#summer_memories_3.xm',
'144405#hillbilly_billyboy.xm',
'154795#4mat_-_eternity.xm',
'155845#bookworm.mo3',
'155914#battleofsteel.xm',
'158975#1_channel_moog.it',
'165495#trans.s3m',
'168513#necros_-_introspection.s3m',
'169628#radix_-_feng_shui_schematics.xm',
'175238#unknown48_-_twilight.mod',
'33432#ambrozia.xm',
'33460#amigatre.mod',
'34594#CHARIOT.S3M',
'34596#BUTTERFL.XM',
'34654#CTGOBLIN.S3M',
'35151#bananasplit.mod',
'35280#DEADLOCK.XM',
'38591#compo_liam.xm',
'39987#crystald.s3m',
'40475#ELYSIUM.MOD',
'42146#enigma.mod',
'42519#GHOST2.MOD',
'42560#GSLINGER.MOD',
'42872#existing.xm',
'50427#nf-stven.xm',
'51549#overture.mod',
'54250#SATELL.S3M',
'54313#realmk.s3m',
'55789#scrambld.mod',
'57934#spacedeb.mod',
'59344#stardstm.mod',
'60395#2ND_PM.S3M',
'66187#external.xm',
'66343#beek-substitutionology.it',
'67561#radix-unreal_superhero.xm',
'70829#inside_out.s3m',
'83779#beyond_music.mod',
]
MUSIC_SNES = [
'actr',
'crock',
'ct',
'dkc',
'dkq',
'ff6',
'fz',
'loz3',
'mmx',
'ptws',
'scv4',
'sf',
'sf2',
'sgng',
'smk',
'smw',
'yi',
'zamn'
]
'actr',
'crock',
'ct',
'dkc',
'dkq',
'ff6',
'fz',
'loz3',
'mmx',
'ptws',
'scv4',
'sf',
'sf2',
'sgng',
'smk',
'smw',
'yi',
'zamn'
]
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,326 @@
# Wizard Kit: Settings - Partition UIDs
# sources: https://en.wikipedia.org/wiki/GUID_Partition_Table
# https://en.wikipedia.org/wiki/Partition_type
# NOTE: Info has been trimmed for brevity. As such, there may be some inaccuracy.
PARTITION_UIDS = {
'00': {'OS': 'All','Description': 'Empty partition entry'},
'01': {'OS': 'DOS','Description': 'FAT12 as primary partition'},
'02': {'OS': 'XENIX','Description': 'XENIX root'},
'03': {'OS': 'XENIX','Description': 'XENIX usr'},
'04': {'OS': 'DOS','Description': 'FAT16 with less than 32 MB'},
'05': {'OS': 'DOS / SpeedStor','Description': 'Extended partition'},
'06': {'OS': 'DOS1+','Description': 'FAT16B [over 65K sectors]'},
'07': {'OS': 'Windows / OS/2 / QNX 2','Description': 'NTFS/exFAT/HPFS/IFS/QNX'},
'08': {'OS': 'CBM / DOS / OS/2 / AIX /QNX','Description': 'FAT12-16/AIX/QNY/SplitDrive'},
'09': {'OS': 'AIX / QNX / Coherent / OS-9','Description': 'AIX/QNZ/Coherent/RBF'},
'0A': {'OS': 'OS/2 / Coherent','Description': 'Boot Manager / Swap'},
'0B': {'OS': 'DOS','Description': 'FAT32 with CHS addressing'},
'0C': {'OS': 'DOS','Description': 'FAT32 with LBA'},
'0D': {'OS': 'Silicon Safe','Description': 'Reserved'},
'0E': {'OS': 'DOS','Description': 'FAT16B with LBA'},
'0F': {'OS': 'DOS','Description': 'Extended partition with LBA'},
'10': {'OS': 'OPUS','Description': 'Unknown'},
'11': {'OS': 'Leading Edge MS-DOS / OS/2','Description': 'FAT12/FAT16'},
'12': {'OS': 'Compaq Contura','Description': 'conf/diag/hiber/rescue/serv'},
'14': {'OS': 'AST DOS / OS/2 / MaverickOS','Description': 'FAT12/FAT16/Omega'},
'15': {'OS': 'OS/2 / Maverick OS','Description': 'Hidden extended / Swap'},
'16': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT16B'},
'17': {'OS': 'OS/2 Boot Manager','Description': 'Hidden IFS/HPFS/NTFS/exFAT'},
'18': {'OS': 'AST Windows','Description': '0-Volt Suspend/SmartSleep'},
'19': {'OS': 'Willowtech Photon coS','Description': 'Willowtech Photon coS'},
'1B': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT32'},
'1C': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT32 with LBA'},
'1E': {'OS': 'OS/2 Boot Manager','Description': 'Hidden FAT16 with LBA'},
'1F': {'OS': 'OS/2 Boot Manager','Description': 'Hidden extended with LBA'},
'20': {'OS': 'Windows Mobile','Description': 'update XIP/Willowsoft OFS1'},
'21': {'OS': 'Oxygen','Description': 'SpeedStor / FSo2'},
'22': {'OS': 'Oxygen','Description': 'Oxygen Extended Partition'},
'23': {'OS': 'Windows Mobile','Description': 'Reserved / boot XIP'},
'24': {'OS': 'NEC MS-DOS0','Description': 'Logical FAT12 or FAT16'},
'25': {'OS': 'Windows Mobile','Description': 'IMGFS[citation needed]'},
'26': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'27': {'OS': 'Win/PQserv/MirOS/RooterBOOT','Description': 'WinRE/Rescue/MirOS/RooterBOOT'},
'2A': {'OS': 'AtheOS','Description': 'AthFS/AFS/Reserved'},
'2B': {'OS': 'SyllableOS','Description': 'SyllableSecure (SylStor)'},
'31': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'32': {'OS': 'NOS','Description': 'Unknown'},
'33': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'34': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'35': {'OS': 'OS/2 Server /eComStation','Description': 'JFS'},
'36': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'38': {'OS': 'THEOS','Description': 'THEOS version 3.2, 2 GB'},
'39': {'OS': 'Plan 9 / THEOS','Description': 'Plan 9 edition 3 / THEOS v4'},
'3A': {'OS': 'THEOS','Description': 'THEOS v4, 4 GB'},
'3B': {'OS': 'THEOS','Description': 'THEOS v4 extended'},
'3C': {'OS': 'PartitionMagic','Description': 'PqRP (image in progress)'},
'3D': {'OS': 'PartitionMagic','Description': 'Hidden NetWare'},
'3F': {'OS': 'OS/32','Description': 'Unknown'},
'40': {'OS': 'PICK / Venix','Description': 'PICK R83 / Venix 80286'},
'41': {'OS': 'RISC / Linux / PowerPC','Description': 'Boot / Old Linux/Minix'},
'42': {'OS': 'SFS / Linux / Win2K/XP/etc','Description': 'SFS / Old Linux Swap'},
'43': {'OS': 'Linux','Description': 'Old Linux native'},
'44': {'OS': 'GoBack','Description': 'Norton/WildFire/Adaptec/Roxio'},
'45': {'OS': 'Boot-US / EUMEL/ELAN','Description': 'Priam/Boot/EUMEL/ELAN (L2)'},
'46': {'OS': 'EUMEL/ELAN','Description': 'EUMEL/ELAN (L2)'},
'47': {'OS': 'EUMEL/ELAN','Description': 'EUMEL/ELAN (L2)'},
'48': {'OS': 'EUMEL/ELAN','Description': 'EUMEL/ELAN (L2), ERGOS L3'},
'4A': {'OS': 'AdaOS / ALFS/THIN','Description': 'Aquila / ALFS/THIN'},
'4C': {'OS': 'ETH Oberon','Description': 'Aos (A2) file system (76)'},
'4D': {'OS': 'QNX Neutrino','Description': 'Primary QNX POSIX volume'},
'4E': {'OS': 'QNX Neutrino','Description': 'Secondary QNX POSIX volume'},
'4F': {'OS': 'QNX Neutrino / ETH Oberon','Description': '3rd QNX POSIX/Boot/Native'},
'50': {'OS': 'DiskMan4/ETH/LynxOS/Novell','Description': 'Alt FS/Read-only/Lynx RTOS'},
'51': {'OS': 'Disk Manager 4-6','Description': 'R/W partition (Aux 1)'},
'52': {'OS': 'CP/M-80/ System V/AT, V/386','Description': 'CP/M-80'},
'53': {'OS': 'Disk Manager 6','Description': 'Auxiliary 3 (WO)'},
'54': {'OS': 'Disk Manager 6','Description': 'Dynamic Drive Overlay (DDO)'},
'55': {'OS': 'EZ-Drive','Description': 'Maxtor/MaxBlast/DriveGuide'},
'56': {'OS': 'AT&T DOS/EZ-Drive/VFeature','Description': 'FAT12 16/EZ-BIOS/VFeature'},
'57': {'OS': 'DrivePro','Description': 'VNDI partition'},
'5C': {'OS': 'EDISK','Description': 'Priam EDisk Volume'},
'61': {'OS': 'SpeedStor','Description': 'Unknown'},
'63': {'OS': 'Unix','Description': 'Unix,ISC,SysV,ix,BSD,HURD'},
'64': {'OS': 'SpeedStor / NetWare','Description': 'NetWare FS 286/2,PC-ARMOUR'},
'65': {'OS': 'NetWare','Description': 'NetWare File System 386'},
'66': {'OS': 'NetWare / NetWare','Description': 'NetWare FS 386 / SMS'},
'67': {'OS': 'NetWare','Description': 'Wolf Mountain'},
'68': {'OS': 'NetWare','Description': 'Unknown'},
'69': {'OS': 'NetWare 5 / NetWare','Description': 'Novell Storage Services'},
'6E': {'Description': 'Unknown'},
'70': {'OS': 'DiskSecure','Description': 'DiskSecure multiboot'},
'71': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'72': {'OS': 'APTI systems / Unix V7/x86','Description': 'APTI altFAT12 / V7 / x86'},
'73': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'74': {'OS': 'Microsoft, IBM','Description': 'Reserved / Scramdisk'},
'75': {'OS': 'PC/IX','Description': 'Unknown'},
'76': {'OS': 'Microsoft, IBM','Description': 'Reserved'},
'77': {'OS': 'Novell','Description': 'VNDI, M2FS, M2CS'},
'78': {'OS': 'Geurt Vos','Description': 'XOSL bootloader file system'},
'79': {'OS': 'APTI conformant systems','Description': 'APTI altFAT16 (CHS, SFN)'},
'7A': {'OS': 'APTI conformant systems','Description': 'APTI altFAT16 (LBA, SFN)'},
'7B': {'OS': 'APTI conformant systems','Description': 'APTI altFAT16B (CHS, SFN)'},
'7C': {'OS': 'APTI conformant systems','Description': 'APTI altFAT32 (LBA, SFN)'},
'7D': {'OS': 'APTI conformant systems','Description': 'APTI altFAT32 (CHS, SFN)'},
'7E': {'OS': 'F.I.X. (claim) / PrimoCache','Description': 'Level 2 cache'},
'7F': {'OS': 'Varies','Description': 'AltOS DevPartition Standard'},
'80': {'OS': 'Minix 1.1-1.4a','Description': 'Minix file system (old)'},
'81': {'OS': 'Minix 1.4b+ / Linux','Description': 'MINIX FS/Mitac AdvDiskManager'},
'82': {'OS': 'Linux / Sun Microsystems','Description': 'Swap / Solaris x86 / Prime'},
'83': {'OS': 'GNU/Linux','Description': 'Any native Linux FS'},
'84': {'OS': 'OS/2 / Windows 7','Description': 'Hibernat/HiddenC/RapidStart'},
'85': {'OS': 'GNU/Linux','Description': 'Linux extended'},
'86': {'OS': 'Windows NT 4 Server / Linux','Description': 'FAT16B mirror/LinuxRAID-old'},
'87': {'OS': 'Windows NT 4 Server','Description': 'HPFS/NTFS mirrored volume'},
'88': {'OS': 'GNU/Linux','Description': 'Plaintext partition table'},
'8A': {'OS': 'AiR-BOOT','Description': 'Linux kernel image'},
'8B': {'OS': 'Windows NT 4 Server','Description': 'FAT32 mirrored volume set'},
'8C': {'OS': 'Windows NT 4 Server','Description': 'FAT32 mirrored volume set'},
'8D': {'OS': 'Free FDISK','Description': 'Hidden FAT12'},
'8E': {'OS': 'Linux','Description': 'Linux LVM'},
'90': {'OS': 'Free FDISK','Description': 'Hidden FAT16'},
'91': {'OS': 'Free FDISK','Description': 'Hidden extended partition'},
'92': {'OS': 'Free FDISK','Description': 'Hidden FAT16B'},
'93': {'OS': 'Amoeba / Linux','Description': 'Amoeba native/Hidden Linux'},
'94': {'OS': 'Amoeba','Description': 'Amoeba bad block table'},
'95': {'OS': 'EXOPC','Description': 'EXOPC native'},
'96': {'OS': 'CHRP','Description': 'ISO-9660 file system'},
'97': {'OS': 'Free FDISK','Description': 'Hidden FAT32'},
'98': {'OS': 'Free FDISK / ROM-DOS','Description': 'Hidden FAT32 / service part'},
'99': {'OS': 'early Unix','Description': 'Unknown'},
'9A': {'OS': 'Free FDISK','Description': 'Hidden FAT16'},
'9B': {'OS': 'Free FDISK','Description': 'Hidden extended partition'},
'9E': {'OS': 'VSTA / ForthOS','Description': 'ForthOS (eForth port)'},
'9F': {'OS': 'BSD/OS 3.0+, BSDI','Description': 'Unknown'},
'A0': {'OS': 'HP/Phoenix/IBM/Toshiba/Sony','Description': 'Diagnostic for HP/Hibernate'},
'A1': {'OS': 'HP / Phoenix, NEC','Description': 'HP Vol Expansion/Hibernate'},
'A2': {'OS': 'Cyclone V','Description': 'Hard Processor System (HPS)'},
'A3': {'OS': 'HP','Description': 'HP Vol Expansion(SpeedStor)'},
'A4': {'OS': 'HP','Description': 'HP Vol Expansion(SpeedStor)'},
'A5': {'OS': 'BSD','Description': 'BSD slice'},
'A6': {'OS': 'OpenBSD','Description': 'HP Vol Expansion/BSD slice'},
'A7': {'OS': 'NeXT','Description': 'NeXTSTEP'},
'A8': {'OS': 'Darwin, Mac OS X','Description': 'Apple Darwin, Mac OS X UFS'},
'A9': {'OS': 'NetBSD','Description': 'NetBSD slice'},
'AA': {'OS': 'MS-DOS','Description': 'Olivetti DOS FAT12(1.44 MB)'},
'AB': {'OS': 'Darwin, Mac OS X / GO! OS','Description': 'Apple Darwin/OS X boot/GO!'},
'AD': {'OS': 'RISC OS','Description': 'ADFS / FileCore format'},
'AE': {'OS': 'ShagOS','Description': 'ShagOS file system'},
'AF': {'OS': 'ShagOS','Description': 'OS X HFS & HFS+/ShagOS Swap'},
'B0': {'OS': 'Boot-Star','Description': 'Boot-Star dummy partition'},
'B1': {'OS': 'QNX 6.x','Description': 'HPVolExpansion/QNX Neutrino'},
'B2': {'OS': 'QNX 6.x','Description': 'QNX Neutrino power-safe FS'},
'B3': {'OS': 'QNX 6.x','Description': 'HPVolExpansion/QNX Neutrino'},
'B4': {'OS': 'HP','Description': 'HP Vol Expansion(SpeedStor)'},
'B6': {'OS': 'Windows NT 4 Server','Description': 'HPVolExpansion/FAT16Bmirror'},
'B7': {'OS': 'BSDI / Windows NT 4 Server','Description': 'BSDI,Swap,HPFS/NTFS mirror'},
'B8': {'OS': 'BSDI (before 3.0)','Description': 'BSDI Swap / native FS'},
'BB': {'OS': 'Acronis/BootWizard/WinNT 4','Description': 'BootWizard/OEM/FAT32 mirror'},
'BC': {'OS': 'Acronis/WinNT/BackupCapsule','Description': 'FAT32RAID/SecureZone/Backup'},
'BD': {'OS': 'BonnyDOS/286','Description': 'Unknown'},
'BE': {'OS': 'Solaris 8','Description': 'Solaris 8 boot'},
'BF': {'OS': 'Solaris','Description': 'Solaris x86'},
'C0': {'OS': 'DR-DOS,MultiuserDOS,REAL/32','Description': 'Secured FAT (under 32 MB)'},
'C1': {'OS': 'DR DOS','Description': 'Secured FAT12'},
'C2': {'OS': 'Power Boot','Description': 'Hidden Linux native FS'},
'C3': {'OS': 'Power Boot','Description': 'Hidden Linux Swap'},
'C4': {'OS': 'DR DOS','Description': 'Secured FAT16'},
'C5': {'OS': 'DR DOS','Description': 'Secured extended partition'},
'C6': {'OS': 'DR DOS / WinNT 4 Server','Description': 'Secured FAT16B/FAT16Bmirror'},
'C7': {'OS': 'Syrinx / WinNT 4 Server','Description': 'Syrinx boot/HPFS/NTFSmirror'},
'C8': {'Description': "DR-DOS Reserved (since '97)"},
'C9': {'Description': "DR-DOS Reserved (since '97)"},
'CA': {'Description': "DR-DOS Reserved (since '97)"},
'CB': {'OS': 'DR-DOSx / WinNT 4 Server','Description': 'Secured FAT32/FAT32 mirror'},
'CC': {'OS': 'DR-DOSx / WinNT 4 Server','Description': 'Secured FAT32/FAT32 mirror'},
'CD': {'OS': 'CTOS','Description': 'Memory dump'},
'CE': {'OS': 'DR-DOSx','Description': 'Secured FAT16B'},
'CF': {'OS': 'DR-DOSx','Description': 'Secured extended partition'},
'D0': {'OS': 'Multiuser DOS, REAL/32','Description': 'Secured FAT (over 32 MB)'},
'D1': {'OS': 'Multiuser DOS','Description': 'Secured FAT12'},
'D4': {'OS': 'Multiuser DOS','Description': 'Secured FAT16'},
'D5': {'OS': 'Multiuser DOS','Description': 'Secured extended partition'},
'D6': {'OS': 'Multiuser DOS','Description': 'Secured FAT16B'},
'D8': {'OS': 'Digital Research','Description': 'CP/M-86 [citation needed]'},
'DA': {'OS': 'Powercopy Backup','Description': 'Non-FS data / Shielded disk'},
'DB': {'OS': 'CP/M-86/CDOS/CTOS/D800/DRMK','Description': 'CP/M-86/ConcDOS/Boot/FAT32'},
'DD': {'OS': 'CTOS','Description': 'Hidden memory dump'},
'DE': {'OS': 'Dell','Description': 'FAT16 utility/diagnostic'},
'DF': {'OS': 'DG/UX / BootIt / Aviion','Description': 'DG/UX Virt DiskMan / EMBRM'},
'E0': {'OS': 'STMicroelectronics','Description': 'ST AVFS'},
'E1': {'OS': 'SpeedStor','Description': 'ExtendedFAT12 >1023cylinder'},
'E2': {'Description': 'DOS read-only (XFDISK)'},
'E3': {'OS': 'SpeedStor','Description': 'DOS read-only'},
'E4': {'OS': 'SpeedStor','Description': 'ExtendedFAT16 <1024cylinder'},
'E5': {'OS': 'Tandy MS-DOS','Description': 'Logical FAT12 or FAT16'},
'E6': {'OS': 'SpeedStor','Description': 'Unknown'},
'E8': {'OS': 'LUKS','Description': 'Linux Unified Key Setup'},
'EB': {'OS': 'BeOS, Haiku','Description': 'BFS'},
'EC': {'OS': 'SkyOS','Description': 'SkyFS'},
'ED': {'OS': 'Sprytix / EDD 4','Description': 'EDC loader / GPT hybrid MBR'},
'EE': {'OS': 'EFI','Description': 'GPT protective MBR'},
'EF': {'OS': 'EFI','Description': 'EFI system partition'},
'F0': {'OS': 'Linux / OS/32','Description': 'PA-RISC Linux boot loader.'},
'F1': {'OS': 'SpeedStor','Description': 'Unknown'},
'F2': {'OS': 'SperryIT DOS/Unisys DOS','Description': 'Logical FAT12/FAT16'},
'F3': {'OS': 'SpeedStor','Description': 'Unknown'},
'F4': {'OS': 'SpeedStor / Prologue','Description': '"large"DOS part/NGF/TwinFS'},
'F5': {'OS': 'Prologue','Description': 'MD0-MD9 part for NGF/TwinFS'},
'F6': {'OS': 'SpeedStor','Description': 'Unknown'},
'F7': {'OS': 'O.S.G. / X1','Description': 'EFAT / Solid State FS'},
'F9': {'OS': 'Linux','Description': 'pCache ext2/ext3 cache'},
'FA': {'OS': 'Bochs','Description': 'x86 emulator'},
'FB': {'OS': 'VMware','Description': 'VMware VMFS partition'},
'FC': {'OS': 'VMware','Description': 'Swap / VMKCORE kernel dump'},
'FD': {'OS': 'Linux / FreeDOS','Description': 'LinuxRAID/Reserved4FreeDOS'},
'FE': {'OS': 'SpeedStor/LANstep/NT/Linux','Description': 'PS/2/DiskAdmin/old LinuxLVM'},
'FF': {'OS': 'XENIX','Description': 'XENIX bad block table'},
'00000000-0000-0000-0000-000000000000': {'Description': 'Unused entry'},
'024DEE41-33E7-11D3-9D69-0008C781F39F': {'Description': 'MBR partition scheme'},
'C12A7328-F81F-11D2-BA4B-00A0C93EC93B': {'Description': 'EFI System partition'},
'21686148-6449-6E6F-744E-656564454649': {'Description': 'BIOS Boot partition'},
'D3BFE2DE-3DAF-11DF-BA40-E3A556D89593': {'Description': 'Intel Fast Flash (iFFS) partition (for Intel Rapid Start technology)'},
'F4019732-066E-4E12-8273-346C5641494F': {'Description': 'Sony boot partition'},
'BFBFAFE7-A34F-448A-9A5B-6213EB736C22': {'Description': 'Lenovo boot partition'},
'E3C9E316-0B5C-4DB8-817D-F92DF00215AE': {'OS': 'Windows', 'Description': 'Microsoft Reserved Partition (MSR)'},
'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7': {'OS': 'Windows', 'Description': 'Basic data partition'},
'5808C8AA-7E8F-42E0-85D2-E1E90434CFB3': {'OS': 'Windows', 'Description': 'Logical Disk Manager (LDM) metadata partition'},
'AF9B60A0-1431-4F62-BC68-3311714A69AD': {'OS': 'Windows', 'Description': 'Logical Disk Manager data partition'},
'DE94BBA4-06D1-4D40-A16A-BFD50179D6AC': {'OS': 'Windows', 'Description': 'Windows Recovery Environment'},
'37AFFC90-EF7D-4E96-91C3-2D7AE055B174': {'OS': 'Windows', 'Description': 'IBM General Parallel File System (GPFS) partition'},
'E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D': {'OS': 'Windows', 'Description': 'Storage Spaces partition'},
'75894C1E-3AEB-11D3-B7C1-7B03A0000000': {'OS': 'HP-UX', 'Description': 'Data partition'},
'E2A1E728-32E3-11D6-A682-7B03A0000000': {'OS': 'HP-UX', 'Description': 'Service Partition'},
'0FC63DAF-8483-4772-8E79-3D69D8477DE4': {'OS': 'Linux', 'Description': 'Linux filesystem data'},
'A19D880F-05FC-4D3B-A006-743F0F84911E': {'OS': 'Linux', 'Description': 'RAID partition'},
'44479540-F297-41B2-9AF7-D131D5F0458A': {'OS': 'Linux', 'Description': 'Root partition (x86)'},
'4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709': {'OS': 'Linux', 'Description': 'Root partition (x86-64)'},
'69DAD710-2CE4-4E3C-B16C-21A1D49ABED3': {'OS': 'Linux', 'Description': 'Root partition (32-bit ARM)'},
'B921B045-1DF0-41C3-AF44-4C6F280D3FAE': {'OS': 'Linux', 'Description': 'Root partition (64-bit ARM)/AArch64)'},
'0657FD6D-A4AB-43C4-84E5-0933C84B4F4F': {'OS': 'Linux', 'Description': 'Swap partition'},
'E6D6D379-F507-44C2-A23C-238F2A3DF928': {'OS': 'Linux', 'Description': 'Logical Volume Manager (LVM) partition'},
'933AC7E1-2EB4-4F13-B844-0E14E2AEF915': {'OS': 'Linux', 'Description': '/home partition'},
'3B8F8425-20E0-4F3B-907F-1A25A76F98E8': {'OS': 'Linux', 'Description': '/srv (server data) partition'},
'7FFEC5C9-2D00-49B7-8941-3EA10A5586B7': {'OS': 'Linux', 'Description': 'Plain dm-crypt partition'},
'CA7D7CCB-63ED-4C53-861C-1742536059CC': {'OS': 'Linux', 'Description': 'LUKS partition'},
'8DA63339-0007-60C0-C436-083AC8230908': {'OS': 'Linux', 'Description': 'Reserved'},
'83BD6B9D-7F41-11DC-BE0B-001560B84F0F': {'OS': 'FreeBSD', 'Description': 'Boot partition'},
'516E7CB4-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Data partition'},
'516E7CB5-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Swap partition'},
'516E7CB6-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Unix File System (UFS) partition'},
'516E7CB8-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'Vinum volume manager partition'},
'516E7CBA-6ECF-11D6-8FF8-00022D09712B': {'OS': 'FreeBSD', 'Description': 'ZFS partition'},
'48465300-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Hierarchical File System Plus (HFS+) partition'},
'55465300-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple UFS'},
'6A898CC3-1DD2-11B2-99A6-080020736631': {'OS': 'OS X Darwin', 'Description': 'ZFS'},
'52414944-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple RAID partition'},
'52414944-5F4F-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple RAID partition, offline'},
'426F6F74-0000-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple Boot partition (Recovery HD)'},
'4C616265-6C00-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple Label'},
'5265636F-7665-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple TV Recovery partition'},
'53746F72-6167-11AA-AA11-00306543ECAC': {'OS': 'OS X Darwin', 'Description': 'Apple Core Storage (i.e. Lion FileVault) partition'},
'6A82CB45-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Boot partition'},
'6A85CF4D-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Root partition'},
'6A87C46F-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Swap partition'},
'6A8B642B-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Backup partition'},
'6A898CC3-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': '/usr partition'},
'6A8EF2E9-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': '/var partition'},
'6A90BA39-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': '/home partition'},
'6A9283A5-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Alternate sector'},
'6A945A3B-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos', 'Description': 'Reserved partition'},
'6A9630D1-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'6A980767-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'6A96237F-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'6A8D2AC7-1DD2-11B2-99A6-080020736631': {'OS': 'Solaris illumos'},
'49F48D32-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'Swap partition'},
'49F48D5A-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'FFS partition'},
'49F48D82-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'LFS partition'},
'49F48DAA-B10E-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'RAID partition'},
'2DB519C4-B10F-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'Concatenated partition'},
'2DB519EC-B10F-11DC-B99B-0019D1879648': {'OS': 'NetBSD', 'Description': 'Encrypted partition'},
'FE3A2A5D-4F32-41A7-B725-ACCC3285A309': {'OS': 'ChromeOS', 'Description': 'ChromeOS kernel'},
'3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC': {'OS': 'ChromeOS', 'Description': 'ChromeOS rootfs'},
'2E0A753D-9E48-43B0-8337-B15192CB1B5E': {'OS': 'ChromeOS', 'Description': 'ChromeOS future use'},
'42465331-3BA3-10F1-802A-4861696B7521': {'OS': 'Haiku', 'Description': 'Haiku BFS'},
'85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Boot partition'},
'85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Data partition'},
'85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Swap partition'},
'0394EF8B-237E-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Unix File System (UFS) partition'},
'85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'Vinum volume manager partition'},
'85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7': {'OS': 'MidnightBSD', 'Description': 'ZFS partition'},
'45B0969E-9B03-4F30-B4C6-B4B80CEFF106': {'OS': 'Ceph', 'Description': 'Ceph Journal'},
'45B0969E-9B03-4F30-B4C6-5EC00CEFF106': {'OS': 'Ceph', 'Description': 'Ceph dm-crypt Encrypted Journal'},
'4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D': {'OS': 'Ceph', 'Description': 'Ceph OSD'},
'4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D': {'OS': 'Ceph', 'Description': 'Ceph dm-crypt OSD'},
'89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE': {'OS': 'Ceph', 'Description': 'Ceph disk in creation'},
'89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE': {'OS': 'Ceph', 'Description': 'Ceph dm-crypt disk in creation'},
'824CC7A0-36A8-11E3-890A-952519AD3F61': {'OS': 'OpenBSD', 'Description': 'Data partition'},
'CEF5A9AD-73BC-4601-89F3-CDEEEEE321A1': {'OS': 'QNX', 'Description': 'Power-safe (QNX6) file system'},
'C91818F9-8025-47AF-89D2-F030D7000C2C': {'OS': 'Plan 9', 'Description': 'Plan 9 partition'},
'9D275380-40AD-11DB-BF97-000C2911D1B8': {'OS': 'VMware ESX', 'Description': 'vmkcore (coredump partition)'},
'AA31E02A-400F-11DB-9590-000C2911D1B8': {'OS': 'VMware ESX', 'Description': 'VMFS filesystem partition'},
'9198EFFC-31C0-11DB-8F78-000C2911D1B8': {'OS': 'VMware ESX', 'Description': 'VMware Reserved'},
'2568845D-2332-4675-BC39-8FA5A4748D15': {'OS': 'Android-IA', 'Description': 'Bootloader'},
'114EAFFE-1552-4022-B26E-9B053604CF84': {'OS': 'Android-IA', 'Description': 'Bootloader2'},
'49A4D17F-93A3-45C1-A0DE-F50B2EBE2599': {'OS': 'Android-IA', 'Description': 'Boot'},
'4177C722-9E92-4AAB-8644-43502BFD5506': {'OS': 'Android-IA', 'Description': 'Recovery'},
'EF32A33B-A409-486C-9141-9FFB711F6266': {'OS': 'Android-IA', 'Description': 'Misc'},
'20AC26BE-20B7-11E3-84C5-6CFDB94711E9': {'OS': 'Android-IA', 'Description': 'Metadata'},
'38F428E6-D326-425D-9140-6E0EA133647C': {'OS': 'Android-IA', 'Description': 'System'},
'A893EF21-E428-470A-9E55-0668FD91A2D9': {'OS': 'Android-IA', 'Description': 'Cache'},
'DC76DDA9-5AC1-491C-AF42-A82591580C0D': {'OS': 'Android-IA', 'Description': 'Data'},
'EBC597D0-2053-4B15-8B64-E0AAC75F4DB1': {'OS': 'Android-IA', 'Description': 'Persistent'},
'8F68CC74-C5E5-48DA-BE91-A0C8C15E9C80': {'OS': 'Android-IA', 'Description': 'Factory'},
'767941D0-2085-11E3-AD3B-6CFDB94711E9': {'OS': 'Android-IA', 'Description': 'Fastboot / Tertiary'},
'AC6D7924-EB71-4DF8-B48D-E267B27148FF': {'OS': 'Android-IA', 'Description': 'OEM'},
'7412F7D5-A156-4B13-81DC-867174929325': {'OS': 'ONIE', 'Description': 'Boot'},
'D4E6E2CD-4469-46F3-B5CB-1BFF57AFC149': {'OS': 'ONIE', 'Description': 'Config'},
'9E1A2D38-C612-4316-AA26-8B49521E5A8B': {'OS': 'PowerPC', 'Description': 'PReP boot'},
'BC13C2FF-59E6-4262-A352-B275FD6F7172': {'OS': 'Freedesktop', 'Description': 'Extended Boot Partition ($BOOT)'},
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,21 @@
# Wizard Kit: Settings - Sensors
import re
# General
TEMP_LIMITS = {
'GREEN': 60,
'YELLOW': 70,
'ORANGE': 80,
'RED': 90,
}
# Regex
REGEX_COLORS = re.compile(r'\033\[\d+;?1?m')
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,194 @@
'''Wizard Kit: Settings - Setup'''
# pylint: disable=bad-continuation,line-too-long
# vim: sts=2 sw=2 ts=2
import os
try:
import winreg
HKU = winreg.HKEY_USERS
HKCR = winreg.HKEY_CLASSES_ROOT
HKCU = winreg.HKEY_CURRENT_USER
HKLM = winreg.HKEY_LOCAL_MACHINE
except ImportError:
if os.name != 'posix':
raise
# General
OTHER_RESULTS = {
'Error': {
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
},
'Warning': {},
}
# Browsers
MOZILLA_FIREFOX_UBO_PATH = r'{}\{}\ublock_origin.xpi'.format(
os.environ.get('PROGRAMFILES'),
r'Mozilla Firefox\distribution\extensions')
SETTINGS_GOOGLE_CHROME = {
r'Software\Google\Chrome\Extensions\cjpalhdlnbpafiamejdnhcphjbkeiagm': {
'SZ Items': {
'update_url': 'https://clients2.google.com/service/update2/crx'},
'WOW64_32': True,
},
r'Software\Google\Chrome\Extensions\pgdnlhfefecpicbbihgmbmffkjpaplco': {
'SZ Items': {
'update_url': 'https://clients2.google.com/service/update2/crx'},
'WOW64_32': True,
},
}
SETTINGS_MOZILLA_FIREFOX_32 = {
r'Software\Mozilla\Firefox\Extensions': {
'SZ Items': {
'uBlock0@raymondhill.net': MOZILLA_FIREFOX_UBO_PATH},
'WOW64_32': True,
},
}
SETTINGS_MOZILLA_FIREFOX_64 = {
r'Software\Mozilla\Firefox\Extensions': {
'SZ Items': {
'uBlock0@raymondhill.net': MOZILLA_FIREFOX_UBO_PATH},
},
}
# Classic Start
SETTINGS_CLASSIC_START = {
r'Software\IvoSoft\ClassicShell\Settings': {},
r'Software\IvoSoft\ClassicStartMenu': {
'DWORD Items': {'ShowedStyle2': 1},
},
r'Software\IvoSoft\ClassicStartMenu\MRU': {},
r'Software\IvoSoft\ClassicStartMenu\Settings': {
'DWORD Items': {'SkipMetro': 1},
'SZ Items': {
'MenuStyle': 'Win7',
'RecentPrograms': 'Recent',
},
},
}
# Explorer
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': {
# Using SOFTWARE in all caps to avoid collision with 32-bit setting below
'DWORD Items': {'AllowTelemetry': 0},
},
r'Software\Microsoft\Windows\CurrentVersion\Policies\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
'WOW64_32': True,
},
r'Software\Policies\Microsoft\Windows\DataCollection': {
'DWORD Items': {'AllowTelemetry': 0},
},
# Disable Wi-Fi Sense
r'Software\Microsoft\PolicyManager\default\WiFi\AllowWiFiHotSpotReporting': {
'DWORD Items': {'Value': 0},
},
r'Software\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots': {
'DWORD Items': {'Value': 0},
},
}
SETTINGS_EXPLORER_USER = {
# Desktop theme
r'Software\Microsoft\Windows\CurrentVersion\Themes\Personalize': {
'Invalid modes': ['Cur'],
'DWORD Items': {
# <= v1809 default
'AppsUseLightTheme': 1,
'SystemUsesLightTheme': 0,
},
},
# Disable features
r'Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager': {
'DWORD Items': {
# Silently installed apps
'SilentInstalledAppsEnabled': 0,
# Tips and Tricks
'SoftLandingEnabled ': 0,
'SubscribedContent-338389Enabled': 0,
},
},
# File Explorer
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced': {
'Invalid modes': ['Cur'],
'DWORD Items': {
# Change default Explorer view to "Computer"
'LaunchTo': 1,
},
},
r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced': {
# Dup path so it Will be applied to all modes
'DWORD Items': {
# Launch Folder Windows in a Separate Process
'SeparateProcess': 1,
},
},
# Hide People bar
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People': {
'Invalid modes': ['Cur'],
'DWORD Items': {'PeopleBand': 0},
},
# Hide Search button / box
r'Software\Microsoft\Windows\CurrentVersion\Search': {
'Invalid modes': ['Cur'],
'DWORD Items': {'SearchboxTaskbarMode': 0},
},
}
# LibreOffice
LIBREOFFICE_XCU_DATA = '''<?xml version="1.0" encoding="UTF-8"?>
<oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item oor:path="/org.openoffice.Setup/Office/Factories/org.openoffice.Setup:Factory['com.sun.star.presentation.PresentationDocument']"><prop oor:name="ooSetupFactoryDefaultFilter" oor:op="fuse"><value>Impress MS PowerPoint 2007 XML</value></prop></item>
<item oor:path="/org.openoffice.Setup/Office/Factories/org.openoffice.Setup:Factory['com.sun.star.sheet.SpreadsheetDocument']"><prop oor:name="ooSetupFactoryDefaultFilter" oor:op="fuse"><value>Calc MS Excel 2007 XML</value></prop></item>
<item oor:path="/org.openoffice.Setup/Office/Factories/org.openoffice.Setup:Factory['com.sun.star.text.TextDocument']"><prop oor:name="ooSetupFactoryDefaultFilter" oor:op="fuse"><value>MS Word 2007 XML</value></prop></item>
<item oor:path="/org.openoffice.Office.Common/Save/Document"><prop oor:name="WarnAlienFormat" oor:op="fuse"><value>false</value></prop></item>
</oor:items>
'''
# Visual C++ Runtimes
VCR_REDISTS = [
{'Name': 'Visual C++ 2010 x32...',
'Cmd': [r'2010sp1\x32\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2010 x64...',
'Cmd': [r'2010sp1\x64\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2012 Update 4 x32...',
'Cmd': [r'2012u4\x32\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2012 Update 4 x64...',
'Cmd': [r'2012u4\x64\vcredist.exe', '/passive', '/norestart']},
{'Name': 'Visual C++ 2013 x32...',
'Cmd': [r'2013\x32\vcredist.exe', '/install',
'/passive', '/norestart']},
{'Name': 'Visual C++ 2013 x64...',
'Cmd': [r'2013\x64\vcredist.exe', '/install',
'/passive', '/norestart']},
{'Name': 'Visual C++ 2017 x32...',
'Cmd': [r'2017\x32\vcredist.exe', '/install',
'/passive', '/norestart']},
{'Name': 'Visual C++ 2017 x64...',
'Cmd': [r'2017\x64\vcredist.exe', '/install',
'/passive', '/norestart']},
]
# Windows Updates
SETTINGS_WINDOWS_UPDATES = {
r'Software\Microsoft\WindowsUpdate\UX\Settings': {
'DWORD Items': {
# Set to non-targeted readiness level
'BranchReadinessLevel': 32,
'DeferFeatureUpdatesPeriodInDays': 60,
},
}
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")

View file

@ -1,202 +1,229 @@
# Wizard Kit: Settings - Sources
'''Wizard Kit: Settings - Sources'''
# pylint: disable=line-too-long
# vim: sts=2 sw=2 ts=2 tw=0
SOURCE_URLS = {
'Adobe Reader DC': 'http://ardownload.adobe.com/pub/adobe/reader/win/AcrobatDC/1801120058/AcroRdrDC1801120058_en_US.exe',
'AdwCleaner': 'https://downloads.malwarebytes.com/file/adwcleaner',
'AIDA64': 'http://download.aida64.com/aida64engineer597.zip',
'aria2': 'https://github.com/aria2/aria2/releases/download/release-1.34.0/aria2-1.34.0-win-32bit-build1.zip',
'Autoruns': 'https://download.sysinternals.com/files/Autoruns.zip',
'BleachBit': 'https://download.bleachbit.org/BleachBit-2.0-portable.zip',
'BlueScreenView32': 'http://www.nirsoft.net/utils/bluescreenview.zip',
'BlueScreenView64': 'http://www.nirsoft.net/utils/bluescreenview-x64.zip',
'Caffeine': 'http://www.zhornsoftware.co.uk/caffeine/caffeine.zip',
'ClassicStartSkin': 'http://www.classicshell.net/forum/download/file.php?id=3001&sid=9a195960d98fd754867dcb63d9315335',
'Du': 'https://download.sysinternals.com/files/DU.zip',
'ERUNT': 'http://www.aumha.org/downloads/erunt.zip',
'Everything32': 'https://www.voidtools.com/Everything-1.4.1.895.x86.zip',
'Everything64': 'https://www.voidtools.com/Everything-1.4.1.895.x64.zip',
'FastCopy': 'http://ftp.vector.co.jp/70/64/2323/FastCopy354_installer.zip',
'Firefox uBO': 'https://addons.mozilla.org/firefox/downloads/file/1056733/ublock_origin-1.16.20-an+fx.xpi',
'HitmanPro32': 'https://dl.surfright.nl/HitmanPro.exe',
'HitmanPro64': 'https://dl.surfright.nl/HitmanPro_x64.exe',
'HWiNFO': 'http://app.oldfoss.com:81/download/HWiNFO/hwi_588.zip',
'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',
'ProduKey64': 'http://www.nirsoft.net/utils/produkey-x64.zip',
'PuTTY': 'https://the.earth.li/~sgtatham/putty/latest/w32/putty.zip',
'RKill': 'https://www.bleepingcomputer.com/download/rkill/dl/10/',
'Samsung Magician': 'https://s3.ap-northeast-2.amazonaws.com/global.semi.static/SAMSUNG_SSD_v5_2_1_180523/CD0CFAC4675B9E502899B41BE00525C3909ECE3AD57CC1A2FB6B74A766B2A1EA/Samsung_Magician_Installer.zip',
'SDIO Themes': 'http://snappy-driver-installer.org/downloads/SDIO_Themes.zip',
'SDIO Torrent': 'http://snappy-driver-installer.org/downloads/SDIO_Update.torrent',
'TDSSKiller': 'https://media.kaspersky.com/utilities/VirusUtilities/EN/tdsskiller.exe',
'TestDisk': 'https://www.cgsecurity.org/testdisk-7.1-WIP.win.zip',
'wimlib32': 'https://wimlib.net/downloads/wimlib-1.12.0-windows-i686-bin.zip',
'wimlib64': 'https://wimlib.net/downloads/wimlib-1.12.0-windows-x86_64-bin.zip',
'Winapp2': 'https://github.com/MoscaDotTo/Winapp2/archive/master.zip',
'WizTree': 'https://antibody-software.com/files/wiztree_3_26_portable.zip',
'XMPlay 7z': 'https://support.xmplay.com/files/16/xmp-7z.zip?v=800962',
'XMPlay Game': 'https://support.xmplay.com/files/12/xmp-gme.zip?v=515637',
'XMPlay RAR': 'https://support.xmplay.com/files/16/xmp-rar.zip?v=409646',
'XMPlay WAModern': 'https://support.xmplay.com/files/10/WAModern.zip?v=207099',
'XMPlay': 'https://support.xmplay.com/files/20/xmplay383.zip?v=298195',
'XYplorerFree': 'https://www.xyplorer.com/download/xyplorer_free_noinstall.zip',
}
'Adobe Reader DC': 'http://ardownload.adobe.com/pub/adobe/reader/win/AcrobatDC/1901020098/AcroRdrDC1901020098_en_US.exe',
'AdwCleaner': 'https://downloads.malwarebytes.com/file/adwcleaner',
'AIDA64': 'http://download.aida64.com/aida64engineer599.zip',
'aria2': 'https://github.com/aria2/aria2/releases/download/release-1.34.0/aria2-1.34.0-win-32bit-build1.zip',
'Autoruns': 'https://download.sysinternals.com/files/Autoruns.zip',
'BleachBit': 'https://download.bleachbit.org/BleachBit-2.0-portable.zip',
'BlueScreenView32': 'http://www.nirsoft.net/utils/bluescreenview.zip',
'BlueScreenView64': 'http://www.nirsoft.net/utils/bluescreenview-x64.zip',
'Caffeine': 'http://www.zhornsoftware.co.uk/caffeine/caffeine.zip',
'ClassicStartSkin': 'http://www.classicshell.net/forum/download/file.php?id=3001&sid=9a195960d98fd754867dcb63d9315335',
'Du': 'https://download.sysinternals.com/files/DU.zip',
'ERUNT': 'http://www.aumha.org/downloads/erunt.zip',
'Everything32': 'https://www.voidtools.com/Everything-1.4.1.935.x86.en-US.zip',
'Everything64': 'https://www.voidtools.com/Everything-1.4.1.935.x64.en-US.zip',
'FastCopy': 'https://fastcopy.jp/archive/FastCopy380_installer.exe',
'Firefox uBO': 'https://addons.mozilla.org/firefox/downloads/file/1709472/ublock_origin-1.18.6-an+fx.xpi',
'HitmanPro32': 'https://dl.surfright.nl/HitmanPro.exe',
'HitmanPro64': 'https://dl.surfright.nl/HitmanPro_x64.exe',
'HWiNFO': 'http://files2.majorgeeks.com/377527622c5325acc1cb937fb149d0de922320c0/systeminfo/hwi_602.zip',
'Intel SSD Toolbox': r'https://downloadmirror.intel.com/28593/eng/Intel%20SSD%20Toolbox%20-%20v3.5.9.exe',
'IOBit_Uninstaller': r'https://portableapps.com/redirect/?a=IObitUninstallerPortable&s=s&d=pa&f=IObitUninstallerPortable_7.5.0.7.paf.exe',
'KVRT': 'http://devbuilds.kaspersky-labs.com/devbuilds/KVRT/latest/full/KVRT.exe',
'LibreOffice': 'https://download.documentfoundation.org/libreoffice/stable/6.2.4/win/x86_64/LibreOffice_6.2.4_Win_x64.msi',
'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.6.4/npp.7.6.4.bin.minimalist.7z',
'Office Deployment Tool': 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_11509-33604.exe',
'ProduKey32': 'http://www.nirsoft.net/utils/produkey.zip',
'ProduKey64': 'http://www.nirsoft.net/utils/produkey-x64.zip',
'PuTTY': 'https://the.earth.li/~sgtatham/putty/latest/w32/putty.zip',
'RKill': 'https://www.bleepingcomputer.com/download/rkill/dl/10/',
'Samsung Magician': 'https://s3.ap-northeast-2.amazonaws.com/global.semi.static/SAMSUNG_SSD_v5_3_0_181121/CD0C7CC1BE00525FAC4675B9E502899B41D5C3909ECE3AA2FB6B74A766B2A1EA/Samsung_Magician_Installer.zip',
'SDIO Themes': 'http://snappy-driver-installer.org/downloads/SDIO_Themes.zip',
'SDIO Torrent': 'http://snappy-driver-installer.org/downloads/SDIO_Update.torrent',
'TDSSKiller': 'https://media.kaspersky.com/utilities/VirusUtilities/EN/tdsskiller.exe',
'TestDisk': 'https://www.cgsecurity.org/testdisk-7.1-WIP.win.zip',
'wimlib32': 'https://wimlib.net/downloads/wimlib-1.13.1-windows-i686-bin.zip',
'wimlib64': 'https://wimlib.net/downloads/wimlib-1.13.1-windows-x86_64-bin.zip',
'Winapp2': 'https://github.com/MoscaDotTo/Winapp2/archive/master.zip',
'WizTree': 'https://antibody-software.com/files/wiztree_3_28_portable.zip',
'XMPlay 7z': 'https://support.xmplay.com/files/16/xmp-7z.zip?v=800962',
'XMPlay Game': 'https://support.xmplay.com/files/12/xmp-gme.zip?v=515637',
'XMPlay RAR': 'https://support.xmplay.com/files/16/xmp-rar.zip?v=409646',
'XMPlay WAModern': 'https://support.xmplay.com/files/10/WAModern.zip?v=207099',
'XMPlay': 'https://support.xmplay.com/files/20/xmplay383.zip?v=298195',
'XYplorerFree': 'https://www.xyplorer.com/download/xyplorer_free_noinstall.zip',
}
VCREDIST_SOURCES = {
'2010sp1': {
'32': 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe',
'64': 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe',
},
'2012u4': {
'32': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe',
'64': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe',
},
'2013': {
'32': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe',
'64': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe',
},
'2017': {
'32': 'https://aka.ms/vs/15/release/vc_redist.x86.exe',
'64': 'https://aka.ms/vs/15/release/vc_redist.x64.exe',
},
}
'2010sp1': {
'32': 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe',
'64': 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe',
},
'2012u4': {
'32': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe',
'64': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe',
},
'2013': {
'32': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe',
'64': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe',
},
'2017': {
'32': 'https://aka.ms/vs/15/release/vc_redist.x86.exe',
'64': 'https://aka.ms/vs/15/release/vc_redist.x64.exe',
},
}
NINITE_REGEX = {
'base': ['7-Zip', 'VLC'],
'standard': ['Google Chrome', 'Mozilla Firefox', 'SumatraPDF'],
'standard7': ['Google Chrome', 'Mozilla Firefox', 'SumatraPDF'],
}
NINITE_SOURCES = {
'Bundles': {
'Legacy.exe': '.net4.7.2-7zip-chrome-firefox-vlc',
'Modern.exe': '.net4.7.2-7zip-chrome-classicstart-firefox-vlc',
},
'Audio-Video': {
'AIMP.exe': 'aimp',
'Audacity.exe': 'audacity',
'CCCP.exe': 'cccp',
'Foobar2000.exe': 'foobar',
'GOM.exe': 'gom',
'HandBrake.exe': 'handbrake',
'iTunes.exe': 'itunes',
'K-Lite Codecs.exe': 'klitecodecs',
'MediaMonkey.exe': 'mediamonkey',
'MusicBee.exe': 'musicbee',
'Spotify.exe': 'spotify',
'VLC.exe': 'vlc',
'Winamp.exe': 'winamp',
},
'Cloud Storage': {
'Dropbox.exe': 'dropbox',
'Google Backup & Sync.exe': 'googlebackupandsync',
'Mozy.exe': 'mozy',
'OneDrive.exe': 'onedrive',
'SugarSync.exe': 'sugarsync',
},
'Communication': {
'Discord': 'discord',
'Pidgin.exe': 'pidgin',
'Skype.exe': 'skype',
'Trillian.exe': 'trillian',
},
'Compression': {
'7-Zip.exe': '7zip',
'PeaZip.exe': 'peazip',
'WinRAR.exe': 'winrar',
},
'Developer': {
'Eclipse.exe': 'eclipse',
'JDK 8.exe': 'jdk8',
'JDK 8 (x64).exe': 'jdkx8',
'Notepad++.exe': 'notepadplusplus',
'PuTTY.exe': 'putty',
'Python 2.exe': 'python',
'Visual Studio Code.exe': 'vscode',
'WinMerge.exe': 'winmerge',
'WinSCP.exe': 'winscp',
},
'File Sharing': {
'qBittorrent.exe': 'qbittorrent',
},
'Image-Photo': {
'Blender.exe': 'blender',
'FastStone.exe': 'faststone',
'GIMP.exe': 'gimp',
'Greenshot.exe': 'greenshot',
'Inkscape.exe': 'inkscape',
'IrfanView.exe': 'irfanview',
'Krita.exe': 'krita',
'Paint.NET.exe': 'paint.net',
'ShareX.exe': 'sharex',
'XnView.exe': 'xnview',
},
'Misc': {
'Evernote.exe': 'evernote',
'Everything.exe': 'everything',
'KeePass 2.exe': 'keepass2',
'Google Earth.exe': 'googleearth',
'NV Access.exe': 'nvda',
'Steam.exe': 'steam',
},
'Office': {
'CutePDF.exe': 'cutepdf',
'Foxit Reader.exe': 'foxit',
'LibreOffice.exe': 'libreoffice',
'OpenOffice.exe': 'openoffice',
'PDFCreator.exe': 'pdfcreator',
'SumatraPDF.exe': 'sumatrapdf',
'Thunderbird.exe': 'thunderbird',
},
'Runtimes': {
'Adobe Air.exe': 'air',
'dotNET.exe': '.net4.7.2',
'Java 8.exe': 'java8',
'Shockwave.exe': 'shockwave',
'Silverlight.exe': 'silverlight',
},
'Security': {
'Avast.exe': 'avast',
'AVG.exe': 'avg',
'Avira.exe': 'avira',
'Microsoft Security Essentials.exe': 'essentials',
'Malwarebytes Anti-Malware.exe': 'malwarebytes',
'Spybot 2.exe': 'spybot2',
'SUPERAntiSpyware.exe': 'super',
},
'Utilities': {
'CDBurnerXP.exe': 'cdburnerxp',
'Classic Start.exe': 'classicstart',
'Glary Utilities.exe': 'glary',
'ImgBurn.exe': 'imgburn',
'InfraRecorder.exe': 'infrarecorder',
'Launchy.exe': 'launchy',
'RealVNC.exe': 'realvnc',
'Revo Uninstaller.exe': 'revo',
'TeamViewer 13.exe': 'teamviewer13',
'TeraCopy.exe': 'teracopy',
'WinDirStat.exe': 'windirstat',
},
'Web Browsers': {
'Google Chrome.exe': 'chrome',
'Mozilla Firefox.exe': 'firefox',
'Opera Chromium.exe': 'operaChromium',
},
}
'Bundles': {
'base.exe': '.net4.7.2-7zip-vlc',
'base-standard.exe': '.net4.7.2-7zip-chrome-classicstart-firefox-sumatrapdf-vlc',
'base-standard7.exe': '.net4.7.2-7zip-chrome-firefox-sumatrapdf-vlc',
'standard.exe': 'chrome-classicstart-firefox-sumatrapdf',
'standard7.exe': 'chrome-firefox-sumatrapdf',
},
'Audio-Video': {
'AIMP.exe': 'aimp',
'Audacity.exe': 'audacity',
'CCCP.exe': 'cccp',
'Foobar2000.exe': 'foobar',
'GOM.exe': 'gom',
'HandBrake.exe': 'handbrake',
'iTunes.exe': 'itunes',
'K-Lite Codecs.exe': 'klitecodecs',
'MediaMonkey.exe': 'mediamonkey',
'MusicBee.exe': 'musicbee',
'Spotify.exe': 'spotify',
'VLC.exe': 'vlc',
'Winamp.exe': 'winamp',
},
'Cloud Storage': {
'Dropbox.exe': 'dropbox',
'Google Backup & Sync.exe': 'googlebackupandsync',
'Mozy.exe': 'mozy',
'OneDrive.exe': 'onedrive',
'SugarSync.exe': 'sugarsync',
},
'Communication': {
'Discord.exe': 'discord',
'Pidgin.exe': 'pidgin',
'Skype.exe': 'skype',
'Trillian.exe': 'trillian',
},
'Compression': {
'7-Zip.exe': '7zip',
'PeaZip.exe': 'peazip',
'WinRAR.exe': 'winrar',
},
'Developer': {
'Eclipse.exe': 'eclipse',
'Notepad++.exe': 'notepadplusplus',
'PuTTY.exe': 'putty',
'Python 2.exe': 'python',
'Visual Studio Code.exe': 'vscode',
'WinMerge.exe': 'winmerge',
'WinSCP.exe': 'winscp',
},
'File Sharing': {
'qBittorrent.exe': 'qbittorrent',
},
'Image-Photo': {
'Blender.exe': 'blender',
'FastStone.exe': 'faststone',
'GIMP.exe': 'gimp',
'Greenshot.exe': 'greenshot',
'Inkscape.exe': 'inkscape',
'IrfanView.exe': 'irfanview',
'Krita.exe': 'krita',
'Paint.NET.exe': 'paint.net',
'ShareX.exe': 'sharex',
'XnView.exe': 'xnview',
},
'Misc': {
'Evernote.exe': 'evernote',
'Everything.exe': 'everything',
'KeePass 2.exe': 'keepass2',
'Google Earth.exe': 'googleearth',
'NV Access.exe': 'nvda',
'Steam.exe': 'steam',
},
'Office': {
'CutePDF.exe': 'cutepdf',
'Foxit Reader.exe': 'foxit',
'LibreOffice.exe': 'libreoffice',
'OpenOffice.exe': 'openoffice',
'PDFCreator.exe': 'pdfcreator',
'SumatraPDF.exe': 'sumatrapdf',
'Thunderbird.exe': 'thunderbird',
},
'Runtimes': {
'Adobe Air.exe': 'air',
'dotNET.exe': '.net4.7.2',
'Shockwave.exe': 'shockwave',
'Silverlight.exe': 'silverlight',
},
'Security': {
'Avast.exe': 'avast',
'AVG.exe': 'avg',
'Avira.exe': 'avira',
'Microsoft Security Essentials.exe': 'essentials',
'Malwarebytes Anti-Malware.exe': 'malwarebytes',
'Spybot 2.exe': 'spybot2',
'SUPERAntiSpyware.exe': 'super',
},
'Utilities': {
'CDBurnerXP.exe': 'cdburnerxp',
'Classic Start.exe': 'classicstart',
'Glary Utilities.exe': 'glary',
'ImgBurn.exe': 'imgburn',
'InfraRecorder.exe': 'infrarecorder',
'Launchy.exe': 'launchy',
'RealVNC.exe': 'realvnc',
'Revo Uninstaller.exe': 'revo',
'TeamViewer 14.exe': 'teamviewer14',
'TeraCopy.exe': 'teracopy',
'WinDirStat.exe': 'windirstat',
},
'Web Browsers': {
'Google Chrome.exe': 'chrome',
'Mozilla Firefox.exe': 'firefox',
'Opera Chromium.exe': 'operaChromium',
},
}
RST_SOURCES = {
#SetupRST_12.0.exe : Removed from download center?
#SetupRST_12.5.exe : Removed from download center?
#SetupRST_12.8.exe : Removed from download center?
'SetupRST_12.9.exe': 'https://downloadmirror.intel.com/23496/eng/SetupRST.exe',
#SetupRST_13.x.exe : Broken, doesn't support > .NET 4.5
'SetupRST_14.0.exe': 'https://downloadmirror.intel.com/25091/eng/SetupRST.exe',
'SetupRST_14.8.exe': 'https://downloadmirror.intel.com/26759/eng/setuprst.exe',
'SetupRST_15.8.exe': 'https://downloadmirror.intel.com/27442/eng/SetupRST.exe',
'SetupRST_15.9.exe': 'https://downloadmirror.intel.com/27400/eng/SetupRST.exe',
'SetupRST_16.0.exe': 'https://downloadmirror.intel.com/27681/eng/SetupRST.exe',
'SetupRST_16.5.exe': 'https://downloadmirror.intel.com/27984/eng/SetupRST.exe',
}
#SetupRST_12.0.exe : Removed from download center?
#SetupRST_12.5.exe : Removed from download center?
#SetupRST_12.8.exe : Removed from download center?
'SetupRST_12.9.exe': 'https://downloadmirror.intel.com/23496/eng/SetupRST.exe',
#SetupRST_13.x.exe : Broken, doesn't support > .NET 4.5
'SetupRST_14.0.exe': 'https://downloadmirror.intel.com/25091/eng/SetupRST.exe',
'SetupRST_14.8.exe': 'https://downloadmirror.intel.com/26759/eng/setuprst.exe',
'SetupRST_15.8.exe': 'https://downloadmirror.intel.com/27442/eng/SetupRST.exe',
'SetupRST_15.9.exe': 'https://downloadmirror.intel.com/28656/eng/SetupRST.exe',
#SetupRST_16.0.exe : Deprecated by Intel
#SetupRST_16.5.exe : Deprecated by Intel
#SetupRST_16.7.exe : Deprecated by Intel
'SetupRST_16.8.exe': 'https://downloadmirror.intel.com/28653/eng/SetupRST.exe',
'SetupRST_17.2.exe': 'https://downloadmirror.intel.com/28650/eng/SetupRST.exe',
}
WINDOWS_UPDATE_SOURCES = {
'2999226': {
# https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows
'7': {
'32': 'https://download.microsoft.com/download/4/F/E/4FE73868-5EDD-4B47-8B33-CE1BB7B2B16A/Windows6.1-KB2999226-x86.msu',
'64': 'https://download.microsoft.com/download/1/1/5/11565A9A-EA09-4F0A-A57E-520D5D138140/Windows6.1-KB2999226-x64.msu',
},
'8': {
'32': 'https://download.microsoft.com/download/1/E/8/1E8AFE90-5217-464D-9292-7D0B95A56CE4/Windows8-RT-KB2999226-x86.msu',
'64': 'https://download.microsoft.com/download/A/C/1/AC15393F-A6E6-469B-B222-C44B3BB6ECCC/Windows8-RT-KB2999226-x64.msu',
},
'8.1': {
'32': 'https://download.microsoft.com/download/E/4/6/E4694323-8290-4A08-82DB-81F2EB9452C2/Windows8.1-KB2999226-x86.msu',
'64': 'https://download.microsoft.com/download/9/6/F/96FD0525-3DDF-423D-8845-5F92F4A6883E/Windows8.1-KB2999226-x64.msu',
},
},
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=4 sw=4 ts=4 tw=0 nowrap
print("This file is not meant to be called directly.")

View file

@ -0,0 +1,29 @@
# Wizard Kit: Settings - SW Diagnostics
# General
AUTORUNS_SETTINGS = {
r'Software\Sysinternals\AutoRuns': {
'checkvirustotal': 1,
'EulaAccepted': 1,
'shownomicrosoft': 1,
'shownowindows': 1,
'showonlyvirustotal': 1,
'submitvirustotal': 0,
'verifysignatures': 1,
},
r'Software\Sysinternals\AutoRuns\SigCheck': {
'EulaAccepted': 1,
},
r'Software\Sysinternals\AutoRuns\Streams': {
'EulaAccepted': 1,
},
r'Software\Sysinternals\AutoRuns\VirusTotal': {
'VirusTotalTermsAccepted': 1,
},
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -1,56 +1,59 @@
# Wizard Kit: Settings - Tools
TOOLS = {
# NOTE: BinDir will be prepended to these paths at runtime
'AIDA64': {
'32': r'AIDA64\aida64.exe'},
'AutoRuns': {
'32': r'Autoruns\autoruns.exe',
'64': r'Autoruns\autoruns64.exe'},
'BleachBit': {
'32': r'BleachBit\bleachbit_console.exe'},
'Caffeine': {
'32': r'Caffeine\caffeine.exe'},
'Du': {
'32': r'Du\du.exe',
'64': r'Du\du64.exe'},
'ERUNT': {
'32': r'ERUNT\ERUNT.EXE'},
'Everything': {
'32': r'Everything\Everything.exe',
'64': r'Everything\Everything64.exe'},
'FastCopy': {
'32': r'FastCopy\FastCopy.exe',
'64': r'FastCopy\FastCopy64.exe'},
'HitmanPro': {
'32': r'HitmanPro\HitmanPro.exe',
'64': r'HitmanPro\HitmanPro64.exe'},
'HWiNFO': {
'32': r'HWiNFO\HWiNFO.exe',
'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': {
'32': r'ProduKey\ProduKey.exe',
'64': r'ProduKey\ProduKey64.exe'},
'RKill': {
'32': r'RKill\RKill.exe'},
'SevenZip': {
'32': r'7-Zip\7za.exe',
'64': r'7-Zip\7za64.exe'},
'TDSSKiller': {
'32': r'TDSSKiller\TDSSKiller.exe'},
'wimlib-imagex': {
'32': r'wimlib\x32\wimlib-imagex.exe',
'64': r'wimlib\x64\wimlib-imagex.exe'},
'XMPlay': {
'32': r'XMPlay\xmplay.exe'},
}
# NOTE: BinDir will be prepended to these paths at runtime
'AIDA64': {
'32': r'AIDA64\aida64.exe'},
'AutoRuns': {
'32': r'Autoruns\autoruns.exe',
'64': r'Autoruns\autoruns64.exe'},
'BleachBit': {
'32': r'BleachBit\bleachbit_console.exe'},
'Caffeine': {
'32': r'Caffeine\caffeine.exe'},
'Du': {
'32': r'Du\du.exe',
'64': r'Du\du64.exe'},
'ERUNT': {
'32': r'ERUNT\ERUNT.EXE'},
'Everything': {
'32': r'Everything\Everything.exe',
'64': r'Everything\Everything64.exe'},
'FastCopy': {
'32': r'FastCopy\FastCopy.exe',
'64': r'FastCopy\FastCopy64.exe'},
'HitmanPro': {
'32': r'HitmanPro\HitmanPro.exe',
'64': r'HitmanPro\HitmanPro64.exe'},
'HWiNFO': {
'32': r'HWiNFO\HWiNFO.exe',
'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': {
'32': r'ProduKey\ProduKey.exe',
'64': r'ProduKey\ProduKey64.exe'},
'RKill': {
'32': r'RKill\RKill.exe'},
'SevenZip': {
'32': r'7-Zip\7za.exe',
'64': r'7-Zip\7za64.exe'},
'TDSSKiller': {
'32': r'TDSSKiller\TDSSKiller.exe'},
'wimlib-imagex': {
'32': r'wimlib\x32\wimlib-imagex.exe',
'64': r'wimlib\x64\wimlib-imagex.exe'},
'XMPlay': {
'32': r'XMPlay\xmplay.exe'},
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,118 @@
'''Wizard Kit: Settings - UFD'''
# pylint: disable=C0326,E0611
# vim: sts=2 sw=2 ts=2
from collections import OrderedDict
from settings.main import KIT_NAME_FULL,KIT_NAME_SHORT
# General
DOCSTRING = '''WizardKit: Build UFD
Usage:
build-ufd [options] --ufd-device PATH --linux PATH
[--linux-minimal PATH]
[--main-kit PATH]
[--winpe PATH]
[--extra-dir PATH]
build-ufd (-h | --help)
Options:
-d PATH, --linux-dgpu PATH
-e PATH, --extra-dir PATH
-k PATH, --main-kit PATH
-l PATH, --linux PATH
-m PATH, --linux-minimal PATH
-u PATH, --ufd-device PATH
-w PATH, --winpe PATH
-h --help Show this page
-M --use-mbr Use real MBR instead of GPT w/ Protective MBR
-F --force Bypass all confirmation messages. USE WITH EXTREME CAUTION!
-U --update Don't format device, just update
'''
ISO_LABEL = '{}_LINUX'.format(KIT_NAME_SHORT)
UFD_LABEL = '{}_UFD'.format(KIT_NAME_SHORT)
UFD_SOURCES = OrderedDict({
'Linux': {'Arg': '--linux', 'Type': 'ISO'},
'Linux (dGPU)': {'Arg': '--linux-dgpu', 'Type': 'ISO'},
'Linux (Minimal)': {'Arg': '--linux-minimal', 'Type': 'ISO'},
'WinPE': {'Arg': '--winpe', 'Type': 'ISO'},
'Main Kit': {'Arg': '--main-kit', 'Type': 'KIT'},
'Extra Dir': {'Arg': '--extra-dir', 'Type': 'DIR'},
})
# Definitions: Boot entries
BOOT_ENTRIES = {
# Path to check: Comment to remove
'/arch_minimal': 'UFD-MINIMAL',
'/dgpu': 'UFD-DGPU',
'/sources/boot.wim': 'UFD-WINPE',
}
BOOT_FILES = {
# Directory: extension
'/arch/boot/syslinux': 'cfg',
'/EFI/boot': 'conf',
}
# Definitions: Sources and Destinations
## NOTES: Paths are relative to the root of the ISO/UFD
## Sources use rsync's trailing slash syntax
ITEMS = {
'Extra Dir': (
('/', '/'),
),
'Linux': (
('/arch', '/'),
('/isolinux', '/'),
('/EFI/boot', '/EFI/'),
('/EFI/memtest86', '/EFI/'),
),
'Linux (dGPU)': (
('/arch/boot/x86_64/archiso.img', '/dgpu/'),
('/arch/boot/x86_64/vmlinuz', '/dgpu/'),
('/arch/pkglist.x86_64.txt', '/dgpu/'),
('/arch/x86_64', '/dgpu/'),
),
'Linux (Minimal)': (
('/arch/boot/x86_64/archiso.img', '/arch_minimal/'),
('/arch/boot/x86_64/vmlinuz', '/arch_minimal/'),
('/arch/pkglist.x86_64.txt', '/arch_minimal/'),
('/arch/x86_64', '/arch_minimal/'),
),
'Main Kit': (
('/', '/{}/'.format(KIT_NAME_FULL)),
),
'WinPE': (
('/bootmgr', '/'),
('/bootmgr.efi', '/'),
('/en_us', '/'),
('/Boot/', '/boot/'),
('/EFI/Boot/', '/EFI/Microsoft/'),
('/EFI/Microsoft/', '/EFI/Microsoft/'),
('/Boot/BCD', '/sources/'),
('/Boot/boot.sdi', '/sources/'),
('/bootmgr', '/sources/'),
('/sources/boot.wim', '/sources/'),
),
}
ITEMS_HIDDEN = (
# Linux (all versions)
'arch',
'arch_minimal',
'dgpu',
'EFI',
'isolinux',
# Main Kit
'{}/.bin'.format(KIT_NAME_FULL),
'{}/.cbin'.format(KIT_NAME_FULL),
# WinPE
'boot',
'bootmgr',
'bootmgr.efi',
'en-us',
'images',
'sources',
)
if __name__ == '__main__':
print("This file is not meant to be called directly.")

View file

@ -1,185 +1,225 @@
# Wizard Kit: Settings - Windows Builds
'''Wizard Kit: Settings - Windows Builds'''
# pylint: disable=bad-continuation,bad-whitespace
# vim: sts=2 sw=2 ts=2
## NOTE: Data from here: https://en.wikipedia.org/wiki/Windows_10_version_history
WINDOWS_BUILDS = {
# Build Version Release Codename Marketing Name Notes
'6000': ( 'Vista', 'RTM', 'Longhorn', None, 'unsupported'),
'6000': ( 'Vista', 'RTM', 'Longhorn', None, 'unsupported'),
'6001': ( 'Vista', 'SP1', 'Longhorn', None, 'unsupported'),
'6002': ( 'Vista', 'SP2', 'Longhorn', None, 'unsupported'),
# Build, Version, Release, Codename, Marketing Name, Notes
'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'),
'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'),
#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),
'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'),
'9926': ( '10', None, 'Threshold 1', None, 'preview build'),
'10041': ( '10', None, 'Threshold 1', None, 'preview build'),
'10049': ( '10', None, 'Threshold 1', None, 'preview build'),
'10061': ( '10', None, 'Threshold 1', None, 'preview build'),
'10074': ( '10', None, 'Threshold 1', None, 'preview build'),
'10122': ( '10', None, 'Threshold 1', None, 'preview build'),
'10130': ( '10', None, 'Threshold 1', None, 'preview build'),
'10158': ( '10', None, 'Threshold 1', None, 'preview build'),
'10159': ( '10', None, 'Threshold 1', None, 'preview build'),
'10162': ( '10', None, 'Threshold 1', None, 'preview build'),
'10166': ( '10', None, 'Threshold 1', None, 'preview build'),
'10240': ( '10', 'v1507', 'Threshold 1', None, 'unsupported'),
'10525': ( '10', None, 'Threshold 2', None, 'preview build'),
'10532': ( '10', None, 'Threshold 2', None, 'preview build'),
'10547': ( '10', None, 'Threshold 2', None, 'preview build'),
'10565': ( '10', None, 'Threshold 2', None, 'preview build'),
'10576': ( '10', None, 'Threshold 2', None, 'preview build'),
'10586': ( '10', 'v1511', 'Threshold 2', 'November Update', 'unsupported'),
'11082': ( '10', None, 'Redstone 1', None, 'preview build'),
'11099': ( '10', None, 'Redstone 1', None, 'preview build'),
'11102': ( '10', None, 'Redstone 1', None, 'preview build'),
'14251': ( '10', None, 'Redstone 1', None, 'preview build'),
'14257': ( '10', None, 'Redstone 1', None, 'preview build'),
'14271': ( '10', None, 'Redstone 1', None, 'preview build'),
'14279': ( '10', None, 'Redstone 1', None, 'preview build'),
'14291': ( '10', None, 'Redstone 1', None, 'preview build'),
'14295': ( '10', None, 'Redstone 1', None, 'preview build'),
'14316': ( '10', None, 'Redstone 1', None, 'preview build'),
'14328': ( '10', None, 'Redstone 1', None, 'preview build'),
'14332': ( '10', None, 'Redstone 1', None, 'preview build'),
'14342': ( '10', None, 'Redstone 1', None, 'preview build'),
'14352': ( '10', None, 'Redstone 1', None, 'preview build'),
'14361': ( '10', None, 'Redstone 1', None, 'preview build'),
'14366': ( '10', None, 'Redstone 1', None, 'preview build'),
'14367': ( '10', None, 'Redstone 1', None, 'preview build'),
'14371': ( '10', None, 'Redstone 1', None, 'preview build'),
'14372': ( '10', None, 'Redstone 1', None, 'preview build'),
'14376': ( '10', None, 'Redstone 1', None, 'preview build'),
'14379': ( '10', None, 'Redstone 1', None, 'preview build'),
'14383': ( '10', None, 'Redstone 1', None, 'preview build'),
'14385': ( '10', None, 'Redstone 1', None, 'preview build'),
'14388': ( '10', None, 'Redstone 1', None, 'preview build'),
'14390': ( '10', None, 'Redstone 1', None, 'preview build'),
'14393': ( '10', 'v1607', 'Redstone 1', 'Anniversary Update', 'unsupported'),
'14901': ( '10', None, 'Redstone 2', None, 'preview build'),
'14905': ( '10', None, 'Redstone 2', None, 'preview build'),
'14915': ( '10', None, 'Redstone 2', None, 'preview build'),
'14926': ( '10', None, 'Redstone 2', None, 'preview build'),
'14931': ( '10', None, 'Redstone 2', None, 'preview build'),
'14936': ( '10', None, 'Redstone 2', None, 'preview build'),
'14942': ( '10', None, 'Redstone 2', None, 'preview build'),
'14946': ( '10', None, 'Redstone 2', None, 'preview build'),
'14951': ( '10', None, 'Redstone 2', None, 'preview build'),
'14955': ( '10', None, 'Redstone 2', None, 'preview build'),
'14959': ( '10', None, 'Redstone 2', None, 'preview build'),
'14965': ( '10', None, 'Redstone 2', None, 'preview build'),
'14971': ( '10', None, 'Redstone 2', None, 'preview build'),
'14986': ( '10', None, 'Redstone 2', None, 'preview build'),
'15002': ( '10', None, 'Redstone 2', None, 'preview build'),
'15007': ( '10', None, 'Redstone 2', None, 'preview build'),
'15014': ( '10', None, 'Redstone 2', None, 'preview build'),
'15019': ( '10', None, 'Redstone 2', None, 'preview build'),
'15025': ( '10', None, 'Redstone 2', None, 'preview build'),
'15031': ( '10', None, 'Redstone 2', None, 'preview build'),
'15042': ( '10', None, 'Redstone 2', None, 'preview build'),
'15046': ( '10', None, 'Redstone 2', None, 'preview build'),
'15048': ( '10', None, 'Redstone 2', None, 'preview build'),
'15055': ( '10', None, 'Redstone 2', None, 'preview build'),
'15058': ( '10', None, 'Redstone 2', None, 'preview build'),
'15060': ( '10', None, 'Redstone 2', None, 'preview build'),
'15061': ( '10', None, 'Redstone 2', None, 'preview build'),
'15063': ( '10', 'v1703', 'Redstone 2', 'Creators Update', 'outdated'),
'16170': ( '10', None, 'Redstone 3', None, 'preview build'),
'16176': ( '10', None, 'Redstone 3', None, 'preview build'),
'16179': ( '10', None, 'Redstone 3', None, 'preview build'),
'16184': ( '10', None, 'Redstone 3', None, 'preview build'),
'16188': ( '10', None, 'Redstone 3', None, 'preview build'),
'16193': ( '10', None, 'Redstone 3', None, 'preview build'),
'16199': ( '10', None, 'Redstone 3', None, 'preview build'),
'16212': ( '10', None, 'Redstone 3', None, 'preview build'),
'16215': ( '10', None, 'Redstone 3', None, 'preview build'),
'16226': ( '10', None, 'Redstone 3', None, 'preview build'),
'16232': ( '10', None, 'Redstone 3', None, 'preview build'),
'16237': ( '10', None, 'Redstone 3', None, 'preview build'),
'16241': ( '10', None, 'Redstone 3', None, 'preview build'),
'16251': ( '10', None, 'Redstone 3', None, 'preview build'),
'16257': ( '10', None, 'Redstone 3', None, 'preview build'),
'16273': ( '10', None, 'Redstone 3', None, 'preview build'),
'16275': ( '10', None, 'Redstone 3', None, 'preview build'),
'16278': ( '10', None, 'Redstone 3', None, 'preview build'),
'16281': ( '10', None, 'Redstone 3', None, 'preview build'),
'16288': ( '10', None, 'Redstone 3', None, 'preview build'),
'16291': ( '10', None, 'Redstone 3', None, 'preview build'),
'16294': ( '10', None, 'Redstone 3', None, 'preview build'),
'16296': ( '10', None, 'Redstone 3', None, 'preview build'),
'16299': ( '10', 'v1709', 'Redstone 3', 'Fall Creators Update', 'outdated'),
'16353': ( '10', None, 'Redstone 4', None, 'preview build'),
'16362': ( '10', None, 'Redstone 4', None, 'preview build'),
'17004': ( '10', None, 'Redstone 4', None, 'preview build'),
'17017': ( '10', None, 'Redstone 4', None, 'preview build'),
'17025': ( '10', None, 'Redstone 4', None, 'preview build'),
'17035': ( '10', None, 'Redstone 4', None, 'preview build'),
'17040': ( '10', None, 'Redstone 4', None, 'preview build'),
'17046': ( '10', None, 'Redstone 4', None, 'preview build'),
'17063': ( '10', None, 'Redstone 4', None, 'preview build'),
'17074': ( '10', None, 'Redstone 4', None, 'preview build'),
'17083': ( '10', None, 'Redstone 4', None, 'preview build'),
'17093': ( '10', None, 'Redstone 4', None, 'preview build'),
'17101': ( '10', None, 'Redstone 4', None, 'preview build'),
'17107': ( '10', None, 'Redstone 4', None, 'preview build'),
'17110': ( '10', None, 'Redstone 4', None, 'preview build'),
'17112': ( '10', None, 'Redstone 4', None, 'preview build'),
'17115': ( '10', None, 'Redstone 4', None, 'preview build'),
'17120': ( '10', None, 'Redstone 4', None, 'preview build'),
'17123': ( '10', None, 'Redstone 4', None, 'preview build'),
'17127': ( '10', None, 'Redstone 4', None, 'preview build'),
'17128': ( '10', None, 'Redstone 4', None, 'preview build'),
'17133': ( '10', None, 'Redstone 4', None, 'preview build'),
'17134': ( '10', 'v1803', 'Redstone 4', 'April 2018 Update', None),
'17604': ( '10', None, 'Redstone 5', None, 'preview build'),
'17618': ( '10', None, 'Redstone 5', None, 'preview build'),
'17623': ( '10', None, 'Redstone 5', None, 'preview build'),
'17627': ( '10', None, 'Redstone 5', None, 'preview build'),
'17634': ( '10', None, 'Redstone 5', None, 'preview build'),
'17639': ( '10', None, 'Redstone 5', None, 'preview build'),
'17643': ( '10', None, 'Redstone 5', None, 'preview build'),
'17650': ( '10', None, 'Redstone 5', None, 'preview build'),
'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'),
'9841': ('10', None, 'Threshold 1', None, 'preview build'),
'9860': ('10', None, 'Threshold 1', None, 'preview build'),
'9879': ('10', None, 'Threshold 1', None, 'preview build'),
'9926': ('10', None, 'Threshold 1', None, 'preview build'),
'10041': ('10', None, 'Threshold 1', None, 'preview build'),
'10049': ('10', None, 'Threshold 1', None, 'preview build'),
'10061': ('10', None, 'Threshold 1', None, 'preview build'),
'10074': ('10', None, 'Threshold 1', None, 'preview build'),
'10122': ('10', None, 'Threshold 1', None, 'preview build'),
'10130': ('10', None, 'Threshold 1', None, 'preview build'),
'10158': ('10', None, 'Threshold 1', None, 'preview build'),
'10159': ('10', None, 'Threshold 1', None, 'preview build'),
'10162': ('10', None, 'Threshold 1', None, 'preview build'),
'10166': ('10', None, 'Threshold 1', None, 'preview build'),
'10240': ('10', 'v1507', 'Threshold 1', None, 'unsupported'),
'10525': ('10', None, 'Threshold 2', None, 'preview build'),
'10532': ('10', None, 'Threshold 2', None, 'preview build'),
'10547': ('10', None, 'Threshold 2', None, 'preview build'),
'10565': ('10', None, 'Threshold 2', None, 'preview build'),
'10576': ('10', None, 'Threshold 2', None, 'preview build'),
'10586': ('10', 'v1511', 'Threshold 2', 'November Update', 'unsupported'),
'11082': ('10', None, 'Redstone 1', None, 'preview build'),
'11099': ('10', None, 'Redstone 1', None, 'preview build'),
'11102': ('10', None, 'Redstone 1', None, 'preview build'),
'14251': ('10', None, 'Redstone 1', None, 'preview build'),
'14257': ('10', None, 'Redstone 1', None, 'preview build'),
'14271': ('10', None, 'Redstone 1', None, 'preview build'),
'14279': ('10', None, 'Redstone 1', None, 'preview build'),
'14291': ('10', None, 'Redstone 1', None, 'preview build'),
'14295': ('10', None, 'Redstone 1', None, 'preview build'),
'14316': ('10', None, 'Redstone 1', None, 'preview build'),
'14328': ('10', None, 'Redstone 1', None, 'preview build'),
'14332': ('10', None, 'Redstone 1', None, 'preview build'),
'14342': ('10', None, 'Redstone 1', None, 'preview build'),
'14352': ('10', None, 'Redstone 1', None, 'preview build'),
'14361': ('10', None, 'Redstone 1', None, 'preview build'),
'14366': ('10', None, 'Redstone 1', None, 'preview build'),
'14367': ('10', None, 'Redstone 1', None, 'preview build'),
'14371': ('10', None, 'Redstone 1', None, 'preview build'),
'14372': ('10', None, 'Redstone 1', None, 'preview build'),
'14376': ('10', None, 'Redstone 1', None, 'preview build'),
'14379': ('10', None, 'Redstone 1', None, 'preview build'),
'14383': ('10', None, 'Redstone 1', None, 'preview build'),
'14385': ('10', None, 'Redstone 1', None, 'preview build'),
'14388': ('10', None, 'Redstone 1', None, 'preview build'),
'14390': ('10', None, 'Redstone 1', None, 'preview build'),
'14393': ('10', 'v1607', 'Redstone 1', 'Anniversary Update', 'unsupported'),
'14901': ('10', None, 'Redstone 2', None, 'preview build'),
'14905': ('10', None, 'Redstone 2', None, 'preview build'),
'14915': ('10', None, 'Redstone 2', None, 'preview build'),
'14926': ('10', None, 'Redstone 2', None, 'preview build'),
'14931': ('10', None, 'Redstone 2', None, 'preview build'),
'14936': ('10', None, 'Redstone 2', None, 'preview build'),
'14942': ('10', None, 'Redstone 2', None, 'preview build'),
'14946': ('10', None, 'Redstone 2', None, 'preview build'),
'14951': ('10', None, 'Redstone 2', None, 'preview build'),
'14955': ('10', None, 'Redstone 2', None, 'preview build'),
'14959': ('10', None, 'Redstone 2', None, 'preview build'),
'14965': ('10', None, 'Redstone 2', None, 'preview build'),
'14971': ('10', None, 'Redstone 2', None, 'preview build'),
'14986': ('10', None, 'Redstone 2', None, 'preview build'),
'15002': ('10', None, 'Redstone 2', None, 'preview build'),
'15007': ('10', None, 'Redstone 2', None, 'preview build'),
'15014': ('10', None, 'Redstone 2', None, 'preview build'),
'15019': ('10', None, 'Redstone 2', None, 'preview build'),
'15025': ('10', None, 'Redstone 2', None, 'preview build'),
'15031': ('10', None, 'Redstone 2', None, 'preview build'),
'15042': ('10', None, 'Redstone 2', None, 'preview build'),
'15046': ('10', None, 'Redstone 2', None, 'preview build'),
'15048': ('10', None, 'Redstone 2', None, 'preview build'),
'15055': ('10', None, 'Redstone 2', None, 'preview build'),
'15058': ('10', None, 'Redstone 2', None, 'preview build'),
'15060': ('10', None, 'Redstone 2', None, 'preview build'),
'15061': ('10', None, 'Redstone 2', None, 'preview build'),
'15063': ('10', 'v1703', 'Redstone 2', 'Creators Update', 'unsupported'),
'16170': ('10', None, 'Redstone 3', None, 'preview build'),
'16176': ('10', None, 'Redstone 3', None, 'preview build'),
'16179': ('10', None, 'Redstone 3', None, 'preview build'),
'16184': ('10', None, 'Redstone 3', None, 'preview build'),
'16188': ('10', None, 'Redstone 3', None, 'preview build'),
'16193': ('10', None, 'Redstone 3', None, 'preview build'),
'16199': ('10', None, 'Redstone 3', None, 'preview build'),
'16212': ('10', None, 'Redstone 3', None, 'preview build'),
'16215': ('10', None, 'Redstone 3', None, 'preview build'),
'16226': ('10', None, 'Redstone 3', None, 'preview build'),
'16232': ('10', None, 'Redstone 3', None, 'preview build'),
'16237': ('10', None, 'Redstone 3', None, 'preview build'),
'16241': ('10', None, 'Redstone 3', None, 'preview build'),
'16251': ('10', None, 'Redstone 3', None, 'preview build'),
'16257': ('10', None, 'Redstone 3', None, 'preview build'),
'16273': ('10', None, 'Redstone 3', None, 'preview build'),
'16275': ('10', None, 'Redstone 3', None, 'preview build'),
'16278': ('10', None, 'Redstone 3', None, 'preview build'),
'16281': ('10', None, 'Redstone 3', None, 'preview build'),
'16288': ('10', None, 'Redstone 3', None, 'preview build'),
'16291': ('10', None, 'Redstone 3', None, 'preview build'),
'16294': ('10', None, 'Redstone 3', None, 'preview build'),
'16296': ('10', None, 'Redstone 3', None, 'preview build'),
'16299': ('10', 'v1709', 'Redstone 3', 'Fall Creators Update', 'outdated'),
'16353': ('10', None, 'Redstone 4', None, 'preview build'),
'16362': ('10', None, 'Redstone 4', None, 'preview build'),
'17004': ('10', None, 'Redstone 4', None, 'preview build'),
'17017': ('10', None, 'Redstone 4', None, 'preview build'),
'17025': ('10', None, 'Redstone 4', None, 'preview build'),
'17035': ('10', None, 'Redstone 4', None, 'preview build'),
'17040': ('10', None, 'Redstone 4', None, 'preview build'),
'17046': ('10', None, 'Redstone 4', None, 'preview build'),
'17063': ('10', None, 'Redstone 4', None, 'preview build'),
'17074': ('10', None, 'Redstone 4', None, 'preview build'),
'17083': ('10', None, 'Redstone 4', None, 'preview build'),
'17093': ('10', None, 'Redstone 4', None, 'preview build'),
'17101': ('10', None, 'Redstone 4', None, 'preview build'),
'17107': ('10', None, 'Redstone 4', None, 'preview build'),
'17110': ('10', None, 'Redstone 4', None, 'preview build'),
'17112': ('10', None, 'Redstone 4', None, 'preview build'),
'17115': ('10', None, 'Redstone 4', None, 'preview build'),
'17120': ('10', None, 'Redstone 4', None, 'preview build'),
'17123': ('10', None, 'Redstone 4', None, 'preview build'),
'17127': ('10', None, 'Redstone 4', None, 'preview build'),
'17128': ('10', None, 'Redstone 4', None, 'preview build'),
'17133': ('10', None, 'Redstone 4', None, 'preview build'),
'17134': ('10', 'v1803', 'Redstone 4', 'April 2018 Update', 'outdated'),
'17604': ('10', None, 'Redstone 5', None, 'preview build'),
'17618': ('10', None, 'Redstone 5', None, 'preview build'),
'17623': ('10', None, 'Redstone 5', None, 'preview build'),
'17627': ('10', None, 'Redstone 5', None, 'preview build'),
'17634': ('10', None, 'Redstone 5', None, 'preview build'),
'17639': ('10', None, 'Redstone 5', None, 'preview build'),
'17643': ('10', None, 'Redstone 5', None, 'preview build'),
'17650': ('10', None, 'Redstone 5', None, 'preview build'),
'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', None),
'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'),
'18262': ('10', None, '19H1', None, 'preview build'),
'18267': ('10', None, '19H1', None, 'preview build'),
'18272': ('10', None, '19H1', None, 'preview build'),
'18277': ('10', None, '19H1', None, 'preview build'),
'18282': ('10', None, '19H1', None, 'preview build'),
'18290': ('10', None, '19H1', None, 'preview build'),
'18298': ('10', None, '19H1', None, 'preview build'),
'18305': ('10', None, '19H1', None, 'preview build'),
'18309': ('10', None, '19H1', None, 'preview build'),
'18312': ('10', None, '19H1', None, 'preview build'),
'18317': ('10', None, '19H1', None, 'preview build'),
'18323': ('10', None, '19H1', None, 'preview build'),
'18329': ('10', None, '19H1', None, 'preview build'),
'18334': ('10', None, '19H1', None, 'preview build'),
'18342': ('10', None, '19H1', None, 'preview build'),
'18343': ('10', None, '19H1', None, 'preview build'),
'18346': ('10', None, '19H1', None, 'preview build'),
'18348': ('10', None, '19H1', None, 'preview build'),
'18351': ('10', None, '19H1', None, 'preview build'),
'18353': ('10', None, '19H1', None, 'preview build'),
'18356': ('10', None, '19H1', None, 'preview build'),
'18358': ('10', None, '19H1', None, 'preview build'),
'18361': ('10', None, '19H1', None, 'preview build'),
'18362': ('10', 'v1903', '19H1', 'May 2019 Update', None),
'18836': ('10', None, '20H1', None, 'preview build'),
'18841': ('10', None, '20H1', None, 'preview build'),
'18845': ('10', None, '20H1', None, 'preview build'),
'18850': ('10', None, '20H1', None, 'preview build'),
'18855': ('10', None, '20H1', None, 'preview build'),
'18860': ('10', None, '20H1', None, 'preview build'),
'18865': ('10', None, '20H1', None, 'preview build'),
'18875': ('10', None, '20H1', None, 'preview build'),
'18885': ('10', None, '20H1', None, 'preview build'),
'18890': ('10', None, '20H1', None, 'preview build'),
'18894': ('10', None, '20H1', None, 'preview build'),
'18895': ('10', None, '20H1', None, 'preview build'),
'18898': ('10', None, '20H1', None, 'preview build'),
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
print("This file is not meant to be called directly.")

View file

@ -0,0 +1,39 @@
# Wizard Kit: Settings - Windows Setup
# General
WINDOWS_VERSIONS = [
{'Name': 'Windows 7 Home Basic',
'Image File': 'Win7',
'Image Name': 'Windows 7 HOMEBASIC'},
{'Name': 'Windows 7 Home Premium',
'Image File': 'Win7',
'Image Name': 'Windows 7 HOMEPREMIUM'},
{'Name': 'Windows 7 Professional',
'Image File': 'Win7',
'Image Name': 'Windows 7 PROFESSIONAL'},
{'Name': 'Windows 7 Ultimate',
'Image File': 'Win7',
'Image Name': 'Windows 7 ULTIMATE'},
{'Name': 'Windows 8.1',
'Image File': 'Win8',
'Image Name': 'Windows 8.1',
'CRLF': True},
{'Name': 'Windows 8.1 Pro',
'Image File': 'Win8',
'Image Name': 'Windows 8.1 Pro'},
{'Name': 'Windows 10 Home',
'Image File': 'Win10',
'Image Name': 'Windows 10 Home',
'CRLF': True},
{'Name': 'Windows 10 Pro',
'Image File': 'Win10',
'Image Name': 'Windows 10 Pro'},
]
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,57 @@
# Wizard Kit: Settings - WinPE
from settings.data import *
# FastCopy
FAST_COPY_PE_ARGS = [
'/cmd=noexist_only',
'/utf8',
'/skip_empty_dir',
'/linkdest',
'/no_ui',
'/auto_close',
'/exclude={}'.format(';'.join(FAST_COPY_EXCLUDES)),
]
# General
PE_TOOLS = {
'BlueScreenView': {
'Path': r'BlueScreenView\BlueScreenView.exe',
},
'FastCopy': {
'Path': r'FastCopy\FastCopy.exe',
'Args': FAST_COPY_PE_ARGS,
},
'HWiNFO': {
'Path': r'HWiNFO\HWiNFO.exe',
},
'NT Password Editor': {
'Path': r'NT Password Editor\ntpwedit.exe',
},
'Notepad++': {
'Path': r'NotepadPlusPlus\NotepadPlusPlus.exe',
},
'PhotoRec': {
'Path': r'TestDisk\photorec_win.exe',
'Args': ['-new_console:n'],
},
'Prime95': {
'Path': r'Prime95\prime95.exe',
},
'ProduKey': {
'Path': r'ProduKey\ProduKey.exe',
},
'Q-Dir': {
'Path': r'Q-Dir\Q-Dir.exe',
},
'TestDisk': {
'Path': r'TestDisk\testdisk_win.exe',
'Args': ['-new_console:n'],
},
}
if __name__ == '__main__':
print("This file is not meant to be called directly.")
# vim: sts=2 sw=2 ts=2

View file

@ -4,36 +4,37 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.repairs import *
init_global_vars()
os.system('title {}: SFC Tool'.format(KIT_NAME_FULL))
set_log_file('SFC Tool.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: SFC Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
},
'Warning': {
'GenericRepair': 'Repaired',
}}
if ask('Run a SFC scan now?'):
try_and_print(message='SFC scan...',
function=run_sfc_scan, other_results=other_results)
else:
abort()
try:
stay_awake()
clear_screen()
print_info('{}: SFC Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
},
'Warning': {
'GenericRepair': 'Repaired',
}}
if ask('Run a SFC scan now?'):
try_and_print(message='SFC scan...',
function=run_sfc_scan, other_results=other_results)
else:
abort()
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -1,128 +0,0 @@
# Wizard Kit: System Checklist
import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.activation import *
from functions.cleanup import *
from functions.diags import *
from functions.info import *
from functions.product_keys import *
from functions.setup import *
init_global_vars()
os.system('title {}: System Checklist Tool'.format(KIT_NAME_FULL))
set_log_file('System Checklist.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: System Checklist Tool\n'.format(KIT_NAME_FULL))
ticket_number = get_ticket_number()
other_results = {
'Error': {
'BIOSKeyNotFoundError': 'BIOS key not found',
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
'GenericError': 'Unknown Error',
'SecureBootDisabledError': 'Disabled',
},
'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))
# Configure
print_info('Configure')
if global_vars['OS']['Version'] == '10':
try_and_print(message='Explorer...',
function=config_explorer_system, cs='Done')
try_and_print(message='Updating Clock...',
function=update_clock, cs='Done')
# Cleanup
print_info('Cleanup')
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')
try_and_print(message='AIDA64 reports...',
function=run_aida64, cs='Done', other_results=other_results)
try_and_print(message='File listing...',
function=backup_file_list, cs='Done', other_results=other_results)
try_and_print(message='Power plans...',
function=backup_power_plans, cs='Done')
try_and_print(message='Product Keys...', other_results=other_results,
function=run_produkey, cs='Done')
try_and_print(message='Registry...',
function=backup_registry, cs='Done', other_results=other_results)
# User data
print_info('User Data')
show_user_data_summary()
# Summary
print_info('Summary')
try_and_print(message='Operating System:',
function=show_os_name, ns='Unknown', silent_function=False)
try_and_print(message='Activation:',
function=show_os_activation, ns='Unknown', silent_function=False)
if (not windows_is_activated()
and global_vars['OS']['Version'] in ('8', '8.1', '10')):
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()
try_and_print(message='Installed Antivirus:',
function=get_installed_antivirus, ns='Unknown',
other_results=other_results, print_return=True)
try_and_print(message='Installed Office:',
function=get_installed_office, ns='Unknown',
other_results=other_results, print_return=True)
# Play audio, show devices, open Windows updates, and open Activation
try_and_print(message='Opening Device Manager...',
function=open_device_manager, cs='Started')
try_and_print(message='Opening HWiNFO (Sensors)...',
function=run_hwinfo_sensors, cs='Started', other_results=other_results)
try_and_print(message='Opening Windows Updates...',
function=open_windows_updates, cs='Started')
if not windows_is_activated():
try_and_print(message='Opening Windows Activation...',
function=open_windows_activation, cs='Started')
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.')
pause('Press Enter exit...')
exit_script()
except SystemExit:
pass
except:
major_exception()
# vim: sts=4 sw=4 ts=4

View file

@ -4,171 +4,170 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.browsers import *
from functions.diags import *
from functions.info import *
from functions.product_keys import *
from functions.repairs import *
from functions.sw_diags import *
init_global_vars()
os.system('title {}: System Diagnostics Tool'.format(KIT_NAME_FULL))
set_log_file('System Diagnostics.log')
# 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',
),
'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:
stay_awake()
clear_screen()
print_info('{}: System Diagnostics Tool\n'.format(KIT_NAME_FULL))
ticket_number = get_ticket_number()
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
if ENABLED_TICKET_NUMBERS:
print_info('Starting System Diagnostics for Ticket #{}\n'.format(
ticket_number))
# Sanitize Environment
print_info('Sanitizing Environment')
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()
try_and_print(message='Running HitmanPro...',
function=run_hitmanpro, cs='Started', other_results=other_results)
try_and_print(message='Running Autoruns...',
function=run_autoruns, cs='Started', other_results=other_results)
# OS Health Checks
print_info('OS Health Checks')
try_and_print(
message='CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env']),
function=run_chkdsk, other_results=other_results)
try_and_print(message='SFC scan...',
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)
backup_browsers()
try_and_print(message='File listing...',
function=backup_file_list, cs='Done', other_results=other_results)
try_and_print(message='Power plans...',
function=backup_power_plans, cs='Done')
try_and_print(message='Product Keys...',
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:',
function=show_os_name, ns='Unknown', silent_function=False)
try_and_print(message='Activation:',
function=show_os_activation, ns='Unknown', silent_function=False)
try_and_print(message='Installed RAM:',
function=show_installed_ram, ns='Unknown', silent_function=False)
show_free_space()
try_and_print(message='Temp Size:',
function=show_temp_files_size, silent_function=False)
try_and_print(message='Installed Antivirus:',
function=get_installed_antivirus, ns='Unknown',
other_results=other_results, print_return=True)
try_and_print(message='Installed Office:',
function=get_installed_office, ns='Unknown',
other_results=other_results, print_return=True)
try_and_print(message='Product Keys:',
function=get_product_keys, ns='Unknown', print_return=True)
# User data
print_info('User Data')
try:
stay_awake()
clear_screen()
print_info('{}: System Diagnostics Tool\n'.format(KIT_NAME_FULL))
ticket_number = get_ticket_number()
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found',
},
'Warning': {
'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS',
}}
if ENABLED_TICKET_NUMBERS:
print_info('Starting System Diagnostics for Ticket #{}\n'.format(
ticket_number))
show_user_data_summary()
except Exception:
print_error(' Unknown error.')
# Sanitize Environment
print_info('Sanitizing Environment')
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)
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# Re-run if earlier process was stopped.
stay_awake()
# Start diags
print_info('Starting Background Scans')
check_connection()
try_and_print(message='Running HitmanPro...',
function=run_hitmanpro, cs='Started', other_results=other_results)
try_and_print(message='Running Autoruns...',
function=run_autoruns, cs='Started', other_results=other_results)
# OS Health Checks
print_info('OS Health Checks')
try_and_print(
message='CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env']),
function=run_chkdsk, other_results=other_results)
try_and_print(message='SFC scan...',
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)
backup_browsers()
try_and_print(message='File listing...',
function=backup_file_list, cs='Done', other_results=other_results)
try_and_print(message='Power plans...',
function=backup_power_plans, cs='Done')
try_and_print(message='Product Keys...',
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:',
function=show_os_name, ns='Unknown', silent_function=False)
try_and_print(message='Activation:',
function=show_os_activation, ns='Unknown', silent_function=False)
try_and_print(message='Installed RAM:',
function=show_installed_ram, ns='Unknown', silent_function=False)
show_free_space()
try_and_print(message='Temp Size:',
function=show_temp_files_size, silent_function=False)
try_and_print(message='Installed Antivirus:',
function=get_installed_antivirus, ns='Unknown',
other_results=other_results, print_return=True)
try_and_print(message='Installed Office:',
function=get_installed_office, ns='Unknown',
other_results=other_results, print_return=True)
try_and_print(message='Product Keys:',
function=get_product_keys, ns='Unknown', print_return=True)
# User data
print_info('User Data')
try:
show_user_data_summary()
except Exception:
print_error(' Unknown error.')
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
exit_script()
except SystemExit:
pass
except:
major_exception()
# vim: sts=4 sw=4 ts=4
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,355 @@
'''Wizard Kit: System Setup'''
# pylint: disable=wildcard-import,wrong-import-position
# vim: sts=2 sw=2 ts=2
import os
import sys
# Init
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from collections import OrderedDict
from functions.activation import *
from functions.browsers import *
from functions.cleanup import *
from functions.info import *
from functions.product_keys import *
from functions.setup import *
from functions.sw_diags import *
from functions.windows_updates import *
init_global_vars()
os.system('title {}: System Setup'.format(KIT_NAME_FULL))
set_log_file('System Setup.log')
# STATIC VARIABLES
# pylint: disable=bad-whitespace,line-too-long
OTHER_RESULTS = {
'Error': {
'BIOSKeyNotFoundError': 'BIOS KEY NOT FOUND',
'CalledProcessError': 'UNKNOWN ERROR',
'FileNotFoundError': 'FILE NOT FOUND',
'GenericError': 'UNKNOWN ERROR',
'Not4KAlignedError': 'FALSE',
'SecureBootDisabledError': 'DISABLED',
'WindowsUnsupportedError': 'UNSUPPORTED',
},
'Warning': {
'GenericRepair': 'REPAIRED',
'NoProfilesError': 'NO PROFILES FOUND',
'NotInstalledError': 'NOT INSTALLED',
'OSInstalledLegacyError': 'OS INSTALLED LEGACY',
'SecureBootNotAvailError': 'NOT AVAILABLE',
'SecureBootUnknownError': 'UNKNOWN',
'UnsupportedOSError': 'UNSUPPORTED OS',
'WindowsOutdatedError': 'OUTDATED',
},
}
SETUP_ACTIONS = OrderedDict({
# Install software
'Installing Programs': {'Info': True},
'VCR': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': install_vcredists, 'Just run': True,},
'LibreOffice': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': install_libreoffice,
'If answer': 'LibreOffice', 'KWArgs': {'quickstart': False, 'register_mso_types': True, 'use_mso_formats': False, 'vcredist': False},
},
'Ninite bundle': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': install_ninite_bundle, 'KWArgs': {'cs': 'STARTED'},},
# Browsers
'Scanning for browsers': {'Info': True},
'Scan': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': scan_for_browsers, 'Just run': True, 'KWArgs': {'skip_ie': True},},
'Backing up browsers': {'Info': True},
'Backup browsers': {'New': False, 'Dat': True, 'Cur': True, 'HW': False, 'Function': backup_browsers, 'Just run': True,},
# Install extensions
'Installing Extensions': {'Info': True},
'Classic Shell skin': {'New': True, 'Dat': True, 'Cur': False, 'HW': False, 'Function': install_classicstart_skin, 'Win10 only': True,},
'Chrome extensions': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': install_chrome_extensions,},
'Firefox extensions': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': install_firefox_extensions,},
# Configure software'
'Configuring Programs': {'Info': True},
'Browser add-ons': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': install_adblock, 'Just run': True,
'Pause': 'Please enable uBlock Origin for all browsers',
},
'Classic Start': {'New': True, 'Dat': True, 'Cur': False, 'HW': False, 'Function': config_classicstart, 'Win10 only': True,},
'Config Windows Updates': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': config_windows_updates, 'Win10 only': True,},
'Enable Windows Updates': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': enable_windows_updates, 'KWArgs': {'silent': True},},
'Explorer (system)': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': config_explorer_system, 'Win10 only': True,},
'Explorer (user)': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': config_explorer_user, 'Win10 only': True,},
'Restart Explorer': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': restart_explorer,},
'Restore default UAC': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': restore_default_uac,},
'Update Clock': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': update_clock,},
# Cleanup
'Cleaning up': {'Info': True},
'AdwCleaner': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': cleanup_adwcleaner,},
'Desktop': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': cleanup_desktop,},
'KIT_NAME_FULL': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': delete_empty_folders,},
# System Info
'Exporting system info': {'Info': True},
'AIDA64 Report': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': run_aida64,},
'File listing': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': backup_file_list,},
'Power plans': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': backup_power_plans,},
'Product Keys': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': run_produkey,},
'Registry': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': backup_registry,},
# Show Summary
'Summary': {'Info': True},
'Operating System': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': show_os_name, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},},
'Activation': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': show_os_activation, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},},
'BIOS Activation': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': activate_with_bios, 'If not activated': True,},
'Secure Boot': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': check_secure_boot_status, 'KWArgs': {'show_alert': False},},
'Installed RAM': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': show_installed_ram, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},},
'Temp size': {'New': False, 'Dat': False, 'Cur': True, 'HW': False, 'Function': show_temp_files_size, 'KWArgs': {'ns': 'UNKNOWN', 'silent_function': False},},
'Show free space': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': show_free_space, 'Just run': True,},
'Installed AV': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': get_installed_antivirus, 'KWArgs': {'ns': 'UNKNOWN', 'print_return': True},},
'Installed Office': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': get_installed_office, 'KWArgs': {'ns': 'UNKNOWN', 'print_return': True},},
'Partitions 4K aligned': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': check_4k_alignment, 'KWArgs': {'cs': 'TRUE', 'ns': 'FALSE'},},
# Open things
'Opening Programs': {'Info': True},
'Device Manager': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': open_device_manager, 'KWArgs': {'cs': 'STARTED'},},
'HWiNFO sensors': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': run_hwinfo_sensors, 'KWArgs': {'cs': 'STARTED'},},
'Speed test': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': open_speedtest, 'KWArgs': {'cs': 'STARTED'},},
'Windows Updates': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': open_windows_updates, 'KWArgs': {'cs': 'STARTED'},},
'Windows Activation': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Function': open_windows_activation, 'If not activated': True, 'KWArgs': {'cs': 'STARTED'},},
'Sleep': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': sleep, 'Just run': True, 'KWArgs': {'seconds': 3},},
'XMPlay': {'New': True, 'Dat': True, 'Cur': True, 'HW': True, 'Function': run_xmplay, 'KWArgs': {'cs': 'STARTED'},},
})
SETUP_ACTION_KEYS = (
'Function',
'If not activated',
'Info',
'Just run',
'KWArgs',
'Pause',
)
SETUP_QUESTIONS = {
# AV
'MSE': {'New': None, 'Dat': None, 'Cur': None, 'HW': False, 'Ninite': True},
# LibreOffice
'LibreOffice': {'New': None, 'Dat': None, 'Cur': None, 'HW': False, 'Ninite': True},
# Ninite
'Base': {'New': True, 'Dat': True, 'Cur': True, 'HW': False, 'Ninite': True},
'Missing': {'New': False, 'Dat': True, 'Cur': False, 'HW': False, 'Ninite': True},
'Standard': {'New': True, 'Dat': True, 'Cur': False, 'HW': False, 'Ninite': True},
}
# pylint: enable=bad-whitespace,line-too-long
# Functions
def check_os_and_abort():
"""Check OS and prompt to abort if not supported."""
result = try_and_print(
message='OS support status...',
function=check_os_support_status,
cs='GOOD',
)
if not result['CS'] and 'Unsupported' in result['Error']:
print_warning('OS version not supported by this script')
if not ask('Continue anyway? (NOT RECOMMENDED)'):
abort()
def get_actions(setup_mode, answers):
"""Get actions to perform based on setup_mode, returns OrderedDict."""
actions = OrderedDict({})
for _key, _val in SETUP_ACTIONS.items():
_action = {}
_if_answer = _val.get('If answer', False)
_win10_only = _val.get('Win10 only', False)
# Set enabled status
_enabled = _val.get(setup_mode, False)
if _if_answer:
_enabled = _enabled and answers[_if_answer]
if _win10_only:
_enabled = _enabled and global_vars['OS']['Version'] == '10'
_action['Enabled'] = _enabled
# Set other keys
for _sub_key in SETUP_ACTION_KEYS:
_action[_sub_key] = _val.get(_sub_key, None)
# Fix KWArgs
if _action.get('KWArgs', {}) is None:
_action['KWArgs'] = {}
# Handle "special" actions
if _key == 'KIT_NAME_FULL':
# Cleanup WK folders
_key = KIT_NAME_FULL
_action['KWArgs'] = {'folder_path': global_vars['ClientDir']}
elif _key == 'Ninite bundle':
# Add install_ninite_bundle() kwargs
_action['KWArgs'].update({
kw.lower(): kv for kw, kv in answers.items()
if SETUP_QUESTIONS.get(kw, {}).get('Ninite', False)
})
elif _key == 'Explorer (user)':
# Explorer settings (user)
_action['KWArgs'] = {'setup_mode': setup_mode}
# Add to dict
actions[_key] = _action
return actions
def get_answers(setup_mode):
"""Get setup answers based on setup_mode and user input, returns dict."""
answers = {k: v.get(setup_mode, False) for k, v in SETUP_QUESTIONS.items()}
# Answer setup questions as needed
if answers['MSE'] is None and global_vars['OS']['Version'] == '7':
answers.update(get_av_selection())
if answers['LibreOffice'] is None:
answers['LibreOffice'] = ask('Install LibreOffice?')
return answers
def get_av_selection():
"""Get AV selection."""
av_answers = {
'MSE': False,
}
av_options = [
{
'Name': 'Microsoft Security Essentials',
'Disabled': global_vars['OS']['Version'] not in ['7'],
},
]
actions = [
{'Name': 'None', 'Letter': 'N'},
{'Name': 'Quit', 'Letter': 'Q'},
]
# Show menu
selection = menu_select(
'Please select an option to install',
main_entries=av_options,
action_entries=actions)
if selection.isnumeric():
index = int(selection) - 1
if 'Microsoft' in av_options[index]['Name']:
av_answers['MSE'] = True
elif selection == 'Q':
abort()
return av_answers
def get_mode():
"""Get mode via menu_select, returns str."""
setup_mode = None
mode_options = [
{'Name': 'New', 'Display Name': 'New / Clean install (no data)'},
{'Name': 'Dat', 'Display Name': 'Clean install with data migration'},
{'Name': 'Cur', 'Display Name': 'Original OS (post-repair or overinstall)'},
{'Name': 'HW', 'Display Name': 'Hardware service (i.e. no software work)'},
]
actions = [
{'Name': 'Quit', 'Letter': 'Q'},
]
# Get selection
selection = menu_select(
'Please select a setup mode',
main_entries=mode_options,
action_entries=actions)
if selection.isnumeric():
index = int(selection) - 1
setup_mode = mode_options[index]['Name']
elif selection == 'Q':
abort()
return setup_mode
def main():
"""Main function."""
stay_awake()
clear_screen()
# Check installed OS
check_os_and_abort()
# Get setup mode
setup_mode = get_mode()
# Get answers to setup questions
answers = get_answers(setup_mode)
# Get actions to perform
actions = get_actions(setup_mode, answers)
# Perform actions
for action, values in actions.items():
kwargs = values.get('KWArgs', {})
# Print info lines
if values.get('Info', False):
print_info(action)
continue
# Print disabled actions
if not values.get('Enabled', False):
show_data(
message='{}...'.format(action),
data='DISABLED',
warning=True,
)
continue
# Check Windows activation if requested
if values.get('If not activated', False) and windows_is_activated():
# Skip
continue
# Run function
if values.get('Just run', False):
values['Function'](**kwargs)
else:
result = try_and_print(
message='{}...'.format(action),
function=values['Function'],
other_results=OTHER_RESULTS,
**kwargs)
# Wait for Ninite proc(s)
if action == 'Ninite bundle':
print_standard('Waiting for installations to finish...')
try:
for proc in result['Out']:
proc.wait()
except KeyboardInterrupt:
pass
# Pause
if values.get('Pause', False):
print_standard(values['Pause'])
pause()
# Show alert box for SecureBoot issues
try:
check_secure_boot_status(show_alert=True)
except Exception: # pylint: disable=broad-except
# Ignoring exceptions since we just want to show the popup
pass
# Done
pause('Press Enter to exit... ')
if __name__ == '__main__':
try:
main()
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except: # pylint: disable=bare-except
major_exception()

View file

@ -4,25 +4,26 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.product_keys import *
init_global_vars()
os.system('title {}: Transferred Key Finder'.format(KIT_NAME_FULL))
set_log_file('Transferred Keys.log')
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: Transferred Key Finder\n'.format(KIT_NAME_FULL))
try_and_print(message='Searching for keys...',
function=list_clientdir_keys, print_return=True)
try:
stay_awake()
clear_screen()
print_info('{}: Transferred Key Finder\n'.format(KIT_NAME_FULL))
try_and_print(message='Searching for keys...',
function=list_clientdir_keys, print_return=True)
# Done
print_standard('\nDone.')
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
print_standard('\nDone.')
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,142 +4,140 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.update import *
init_global_vars()
os.system('title {}: Kit Update Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__':
try:
clear_screen()
print_info('{}: Kit Update Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
}}
try:
clear_screen()
print_info('{}: Kit Update Tool\n'.format(KIT_NAME_FULL))
other_results = {
'Error': {
'CalledProcessError': 'Unknown Error',
}}
## Prep ##
update_sdio = ask('Update SDI Origin?')
## Prep ##
update_sdio = ask('Update SDI Origin?')
## Download ##
print_success('Downloading tools')
## 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 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)
# 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='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='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)
# Diagnostics
print_info(' Diagnostics')
try_and_print(message='AIDA64...', function=update_aida64, other_results=other_results, width=40)
try_and_print(message='Autoruns...', function=update_autoruns, other_results=other_results, width=40)
try_and_print(message='BleachBit...', function=update_bleachbit, other_results=other_results, width=40)
try_and_print(message='Blue Screen View...', function=update_bluescreenview, other_results=other_results, width=40)
try_and_print(message='ERUNT...', function=update_erunt, other_results=other_results, width=40)
try_and_print(message='Hitman Pro...', function=update_hitmanpro, other_results=other_results, width=40)
try_and_print(message='HWiNFO...', function=update_hwinfo, other_results=other_results, width=40)
try_and_print(message='NirCmd...', function=update_nircmd, other_results=other_results, width=40)
try_and_print(message='ProduKey...', function=update_produkey, other_results=other_results, width=40)
# Drivers
print_info(' Drivers')
try_and_print(message='Intel RST...', function=update_intel_rst, other_results=other_results, width=40)
try_and_print(message='Intel SSD Toolbox...', function=update_intel_ssd_toolbox, other_results=other_results, width=40)
try_and_print(message='Samsing Magician...', function=update_samsung_magician, other_results=other_results, width=40)
if update_sdio:
try_and_print(message='Snappy Driver Installer Origin...', function=update_sdi_origin, other_results=other_results, width=40)
# Drivers
print_info(' Drivers')
try_and_print(message='Intel RST...', function=update_intel_rst, other_results=other_results, width=40)
try_and_print(message='Intel SSD Toolbox...', function=update_intel_ssd_toolbox, other_results=other_results, width=40)
try_and_print(message='Samsing Magician...', function=update_samsung_magician, other_results=other_results, width=40)
if update_sdio:
try_and_print(message='Snappy Driver Installer Origin...', function=update_sdi_origin, other_results=other_results, width=40)
# Installers
print_info(' Installers')
try_and_print(message='Adobe Reader DC...', function=update_adobe_reader_dc, other_results=other_results, width=40)
try_and_print(message='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)
# 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='LibreOffice...', function=update_libreoffice, other_results=other_results, width=40)
try_and_print(message='Macs Fan Control...', function=update_macs_fan_control, other_results=other_results, width=40)
try_and_print(message='MS Office...', function=update_office, other_results=other_results, width=40)
try_and_print(message='Visual C++ Runtimes...', function=update_vcredists, other_results=other_results, width=40)
try_and_print(message='Windows Updates...', function=download_windows_updates, other_results=other_results, width=40)
update_all_ninite(other_results=other_results, width=40)
# Misc
print_info(' Misc')
try_and_print(message='Caffeine...', function=update_caffeine, other_results=other_results, width=40)
try_and_print(message='Classic Start Skin...', function=update_classic_start_skin, other_results=other_results, width=40)
try_and_print(message='Du...', function=update_du, other_results=other_results, width=40)
try_and_print(message='Everything...', function=update_everything, other_results=other_results, width=40)
try_and_print(message='Firefox Extensions...', function=update_firefox_ublock_origin, other_results=other_results, width=40)
try_and_print(message='PuTTY...', function=update_putty, other_results=other_results, width=40)
try_and_print(message='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)
# Misc
print_info(' Misc')
try_and_print(message='Caffeine...', function=update_caffeine, other_results=other_results, width=40)
try_and_print(message='Classic Start Skin...', function=update_classic_start_skin, other_results=other_results, width=40)
try_and_print(message='Du...', function=update_du, other_results=other_results, width=40)
try_and_print(message='Everything...', function=update_everything, other_results=other_results, width=40)
try_and_print(message='Firefox Extensions...', function=update_firefox_ublock_origin, other_results=other_results, width=40)
try_and_print(message='PuTTY...', function=update_putty, other_results=other_results, width=40)
try_and_print(message='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='TDSS Killer...', function=update_tdsskiller, 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='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)
# 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')
## Review ##
print_standard('Please review the results and download/extract any missing items to .cbin')
pause('Press Enter to compress the .cbin items')
## Compress ##
print_success('Compressing tools')
print_info(' _Drivers')
for item in os.scandir(r'{}\_Drivers'.format(global_vars['CBinDir'])):
if not re.search(r'^(_Drivers|.*7z)$', item.name, re.IGNORECASE):
try_and_print(
message='{}...'.format(item.name),
function=compress_and_remove_item,
other_results = other_results,
width=40,
item = item)
print_info(' .cbin')
for item in os.scandir(global_vars['CBinDir']):
if not re.search(r'^(_Drivers|_include|.*7z)$', item.name, re.IGNORECASE):
try_and_print(
message='{}...'.format(item.name),
function=compress_and_remove_item,
other_results = other_results,
width=40,
item = item)
## Compress ##
print_success('Compressing tools')
print_info(' _Drivers')
for item in os.scandir(r'{}\_Drivers'.format(global_vars['CBinDir'])):
if not re.search(r'^(_Drivers|.*7z)$', item.name, re.IGNORECASE):
try_and_print(
message='{}...'.format(item.name),
function=compress_and_remove_item,
other_results = other_results,
width=40,
item = item)
print_info(' .cbin')
for item in os.scandir(global_vars['CBinDir']):
if not re.search(r'^(_Drivers|_include|.*7z)$', item.name, re.IGNORECASE):
try_and_print(
message='{}...'.format(item.name),
function=compress_and_remove_item,
other_results = other_results,
width=40,
item = item)
## 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()):
print_info(' {}'.format(section))
for name, options in sorted(LAUNCHERS[section].items()):
try_and_print(message=name, function=generate_launcher,
section=section, name=name, options=options,
other_results=other_results, width=40)
## Generate Launchers
print_success('Generating launchers')
for section in sorted(LAUNCHERS.keys()):
print_info(' {}'.format(section))
for name, options in sorted(LAUNCHERS[section].items()):
try_and_print(message=name, function=generate_launcher,
section=section, name=name, options=options,
other_results=other_results, width=40)
# 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)
if os.path.exists(source):
try:
shutil.move(source, dest)
except Exception:
print_error(' Failed to rename "{}.cmd" to "{}.cmd"'.format(
'Copy WizardKit', KIT_NAME_FULL))
# 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)
if os.path.exists(source):
try:
shutil.move(source, dest)
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...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# Done
print_standard('\nDone.')
pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -1,87 +0,0 @@
# Wizard Kit: User Checklist
import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.browsers import *
from functions.cleanup import *
from functions.setup import *
init_global_vars()
os.system('title {}: User Checklist Tool'.format(KIT_NAME_FULL))
set_log_file('User Checklist ({USERNAME}).log'.format(**global_vars['Env']))
if __name__ == '__main__':
try:
stay_awake()
clear_screen()
print_info('{}: User Checklist\n'.format(KIT_NAME_FULL))
other_results = {
'Warning': {
'NotInstalledError': 'Not installed',
'NoProfilesError': 'No profiles found',
}}
answer_config_browsers = ask('Install adblock?')
if answer_config_browsers:
answer_reset_browsers = ask(
'Reset browsers to safe defaults first?')
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:
install_adblock()
if global_vars['OS']['Version'] == '10':
if answer_config_classicshell:
try_and_print(message='ClassicStart...',
function=config_classicstart, cs='Done')
if answer_config_explorer_user:
try_and_print(message='Explorer...',
function=config_explorer_user, cs='Done')
if (not answer_config_browsers
and not answer_config_classicshell
and not answer_config_explorer_user):
print_warning(' Skipped')
else:
if not answer_config_browsers:
print_warning(' Skipped')
# Run speedtest
popen_program(['start', '', 'https://fast.com'], shell=True)
# Done
print_standard('\nDone.')
pause('Press Enter to exit...')
exit_script()
except SystemExit:
pass
except:
major_exception()
# vim: sts=4 sw=4 ts=4

View file

@ -4,8 +4,7 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.data import *
from functions.repairs import *
init_global_vars()
@ -13,54 +12,56 @@ os.system('title {}: User Data Transfer Tool'.format(KIT_NAME_FULL))
set_log_file('User Data Transfer.log')
if __name__ == '__main__':
try:
# Prep
stay_awake()
clear_screen()
print_info('{}: User Data Transfer Tool\n'.format(KIT_NAME_FULL))
try:
# Prep
stay_awake()
clear_screen()
print_info('{}: User Data Transfer Tool\n'.format(KIT_NAME_FULL))
# Get backup name prefix
ticket_number = get_ticket_number()
if ENABLED_TICKET_NUMBERS:
backup_prefix = ticket_number
else:
backup_prefix = get_simple_string(prompt='Enter backup name prefix')
backup_prefix = backup_prefix.replace(' ', '_')
# Get backup name prefix
ticket_number = get_ticket_number()
if ENABLED_TICKET_NUMBERS:
backup_prefix = ticket_number
else:
backup_prefix = get_simple_string(prompt='Enter backup name prefix')
backup_prefix = backup_prefix.replace(' ', '_')
# Set destination
folder_path = r'{}\Transfer'.format(KIT_NAME_SHORT)
dest = select_destination(folder_path=folder_path,
prompt='Which disk are we transferring to?')
# Set 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)
# Set source items
source = select_source(backup_prefix)
items = scan_source(source, dest)
# Transfer
clear_screen()
print_info('Transfer Details:\n')
if ENABLED_TICKET_NUMBERS:
show_data('Ticket:', ticket_number)
show_data('Source:', source.path)
show_data('Destination:', dest)
# Transfer
clear_screen()
print_info('Transfer Details:\n')
if ENABLED_TICKET_NUMBERS:
show_data('Ticket:', ticket_number)
show_data('Source:', source.path)
show_data('Destination:', dest)
if (not ask('Proceed with transfer?')):
umount_backup_shares()
abort()
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()
print_info('Transferring Data')
transfer_source(source, dest, items)
try_and_print(message='Removing extra files...',
function=cleanup_transfer, cs='Done', dest_path=dest)
umount_backup_shares()
# Done
try_and_print(message='Running KVRT...',
function=run_kvrt, cs='Started')
print_standard('\nDone.')
pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()
# Done
try_and_print(message='Running KVRT...',
function=run_kvrt, cs='Started')
print_standard('\nDone.')
pause("Press Enter to exit...")
exit_script()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,46 @@
# Wizard Kit: Windows updates
import os
import sys
# Init
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.windows_updates import *
init_global_vars()
os.system('title {}: Windows Updates Tool'.format(KIT_NAME_FULL))
set_log_file('Windows Updates Tool.log')
if __name__ == '__main__':
try:
clear_screen()
print_info('{}: Windows Updates Tool\n'.format(KIT_NAME_FULL))
# Check args
if '--disable' in sys.argv:
disable_windows_updates()
elif '--enable' in sys.argv:
enable_windows_updates()
else:
print_error('Bad mode.')
abort()
# Done
exit_script()
except GenericError as err:
# Failed to complete request, show error(s) and prompt tech
print_standard(' ')
for line in str(err).splitlines():
print_warning(line)
print_standard(' ')
print_error('Error(s) encountered, see above.')
print_standard(' ')
if '--disable' in sys.argv:
print_standard('Please reboot and try again.')
pause('Press Enter to exit... ')
exit_script(1)
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,8 +4,7 @@ import os
import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.winpe_menus import *
# Fix 7-Zip name
TOOLS['SevenZip'].pop('64')
@ -14,9 +13,11 @@ set_title('{}: Root Menu'.format(KIT_NAME_FULL))
set_log_file('WinPE.log')
if __name__ == '__main__':
try:
menu_root()
except SystemExit:
pass
except:
major_exception()
try:
menu_root()
except SystemExit as sys_exit:
exit_script(sys_exit.code)
except:
major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -0,0 +1,7 @@
<Configuration>
<Add OfficeClientEdition="32" Channel="Current">
<Product ID="HomeBusiness2019Retail">
<Language ID="en-us" />
</Product>
</Add>
</Configuration>

View file

@ -0,0 +1,7 @@
<Configuration>
<Add OfficeClientEdition="64" Channel="Current">
<Product ID="HomeBusiness2019Retail">
<Language ID="en-us" />
</Product>
</Add>
</Configuration>

View file

@ -0,0 +1,7 @@
<Configuration>
<Add OfficeClientEdition="32" Channel="Current">
<Product ID="HomeStudent2019Retail">
<Language ID="en-us" />
</Product>
</Add>
</Configuration>

View file

@ -0,0 +1,7 @@
<Configuration>
<Add OfficeClientEdition="64" Channel="Current">
<Product ID="HomeStudent2019Retail">
<Language ID="en-us" />
</Product>
</Add>
</Configuration>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -19,6 +19,7 @@ menuentry "MemTest86" {
icon /EFI/boot/icons/wk_memtest.png
loader /EFI/memtest86/memtestx64.efi
}
menuentry "Linux" {
icon /EFI/boot/icons/wk_arch.png
loader /arch/boot/x86_64/vmlinuz
@ -26,15 +27,32 @@ menuentry "Linux" {
initrd /arch/boot/amd_ucode.img
initrd /arch/boot/x86_64/archiso.img
options "archisobasedir=arch archisolabel=%ARCHISO_LABEL% copytoram loglevel=3"
submenuentry "Linux (i3)" {
add_options "i3"
}
submenuentry "Linux (CLI)" {
add_options "loglevel=4 nomodeset nox"
add_options "nox"
}
#UFD-MINIMAL#submenuentry "Linux (Minimal)" {
#UFD-MINIMAL# loader /arch_minimal/vmlinuz
#UFD-MINIMAL# initrd
#UFD-MINIMAL# initrd /arch/boot/intel_ucode.img
#UFD-MINIMAL# initrd /arch/boot/amd_ucode.img
#UFD-MINIMAL# initrd /arch_minimal/archiso.img
#UFD-MINIMAL# options
#UFD-MINIMAL# options "archisobasedir=arch_minimal archisolabel=%ARCHISO_LABEL% copytoram loglevel=3"
#UFD-MINIMAL#}
}
#UFD#menuentry "WindowsPE" {
#UFD# ostype windows
#UFD# icon /EFI/boot/icons/wk_win.png
#UFD# loader /EFI/microsoft/bootx64.efi
#UFD#}
#UFD-WINPE#menuentry "WindowsPE" {
#UFD-WINPE# ostype windows
#UFD-WINPE# icon /EFI/boot/icons/wk_win.png
#UFD-WINPE# loader /EFI/microsoft/bootx64.efi
#UFD-WINPE#}
#UFD-DGPU#menuentry "Mac dGPU Disable Tool" {
#UFD-DGPU# icon /EFI/boot/icons/dgpu.png
#UFD-DGPU# loader /dgpu/vmlinuz
#UFD-DGPU# initrd /arch/boot/intel_ucode.img
#UFD-DGPU# initrd /arch/boot/amd_ucode.img
#UFD-DGPU# initrd /dgpu/archiso.img
#UFD-DGPU# options "archisobasedir=dgpu archisolabel=%ARCHISO_LABEL% nomodeset"
#UFD-DGPU#}

Some files were not shown because too many files have changed in this diff Show more