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

View file

@ -4,59 +4,60 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.activation import * from functions.activation import *
init_global_vars() init_global_vars()
os.system('title {}: Windows Activation Tool'.format(KIT_NAME_FULL)) os.system('title {}: Windows Activation Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__': if __name__ == '__main__':
try: try:
stay_awake() stay_awake()
clear_screen() clear_screen()
print_info('{}: Windows Activation Tool\n'.format(KIT_NAME_FULL)) print_info('{}: Windows Activation Tool\n'.format(KIT_NAME_FULL))
# Bail early if already activated # Bail early if already activated
if windows_is_activated(): if windows_is_activated():
print_info('This system is already activated') print_info('This system is already activated')
sleep(5) sleep(5)
exit_script() exit_script()
other_results = { other_results = {
'Error': { 'Error': {
'BIOSKeyNotFoundError': 'BIOS key not found.', 'BIOSKeyNotFoundError': 'BIOS key not found.',
}} }}
# Determine activation method # Determine activation method
activation_methods = [ activation_methods = [
{'Name': 'Activate with BIOS key', 'Function': activate_with_bios}, {'Name': 'Activate with BIOS key', 'Function': activate_with_bios},
] ]
if global_vars['OS']['Version'] not in ('8', '8.1', '10'): if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
activation_methods[0]['Disabled'] = True activation_methods[0]['Disabled'] = True
actions = [ actions = [
{'Name': 'Quit', 'Letter': 'Q'}, {'Name': 'Quit', 'Letter': 'Q'},
] ]
while True: while True:
selection = menu_select( selection = menu_select(
'{}: Windows Activation Menu'.format(KIT_NAME_FULL), '{}: Windows Activation Menu'.format(KIT_NAME_FULL),
main_entries=activation_methods, action_entries=actions) main_entries=activation_methods, action_entries=actions)
if (selection.isnumeric()): if (selection.isnumeric()):
result = try_and_print( result = try_and_print(
message = activation_methods[int(selection)-1]['Name'], message = activation_methods[int(selection)-1]['Name'],
function = activation_methods[int(selection)-1]['Function'], function = activation_methods[int(selection)-1]['Function'],
other_results=other_results) other_results=other_results)
if result['CS']: if result['CS']:
break break
else: else:
sleep(2) sleep(2)
elif selection == 'Q': elif selection == 'Q':
exit_script()
# Done
print_success('\nDone.')
pause("Press Enter to exit...")
exit_script() exit_script()
except SystemExit:
pass # Done
except: print_success('\nDone.')
major_exception() 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 # pylint: disable=no-name-in-module,wildcard-import,wrong-import-position
# # vim: sts=2 sw=2 ts=2
# Based on a template by BASH3 Boilerplate v2.3.0 """Wizard Kit: UFD build tool"""
# http://bash3boilerplate.sh/#authors
# import os
# The MIT License (MIT) import sys
# Copyright (c) 2013 Kevin van Zonneveld and contributors
# You are not obligated to bundle the LICENSE file with your b3bp projects as long # Init
# as you leave these references intact in the header comments of your source files. sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from docopt import docopt
# Exit on error. Append "|| true" if you expect an error. from functions.common import *
set -o errexit from functions.ufd import *
# Exit on error inside any functions or subshells. from settings.ufd import *
set -o errtrace init_global_vars(silent=True)
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
set -o nounset # Main section
# Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip` if __name__ == '__main__':
set -o pipefail # pylint: disable=invalid-name
# Turn on traces, useful while debugging but commented out by default # Set log
# set -o xtrace try:
global_vars['LogDir'] = '{}/Logs'.format(
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then get_user_home(get_user_name()))
__i_am_main_script="0" # false set_log_file('Build UFD ({Date-Time}).log'.format(**global_vars))
except: # pylint: disable=bare-except
if [[ "${__usage+x}" ]]; then major_exception()
if [[ "${BASH_SOURCE[1]}" = "${0}" ]]; then
__i_am_main_script="1" # true # Header
fi print_success(KIT_NAME_FULL)
print_standard('UFD Build Tool')
__b3bp_external_usage="true" print_standard(' ')
__b3bp_tmp_source_idx=1
fi # Check if running as root
else if not running_as_root():
__i_am_main_script="1" # true print_error('ERROR: This script is meant to be run as root.')
[[ "${__usage+x}" ]] && unset -v __usage abort(False)
[[ "${__helptext+x}" ]] && unset -v __helptext
fi # Docopt
try:
# Set magic variables for current file, directory, os, etc. args = docopt(DOCSTRING)
__dir="$(cd "$(dirname "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" && pwd)" except SystemExit as sys_exit:
__file="${__dir}/$(basename "${BASH_SOURCE[${__b3bp_tmp_source_idx:-0}]}")" # Catch docopt exits
__base="$(basename "${__file}" .sh)" exit_script(sys_exit.code)
__wd="$(pwd)" except: # pylint: disable=bare-except
__usage_example="Usage: sudo $(basename "${0}") --ufd-device [device] --linux-iso [path] --main-kit [path] --winpe-iso [path]" major_exception()
__all_args=""
for a in "${@}"; do try:
if [[ "${a:0:1}" == "-" ]]; then # Verify selections
__all_args="${__all_args} ${a}" ufd_dev = verify_ufd(args['--ufd-device'])
else sources = verify_sources(args, UFD_SOURCES)
__all_args="${__all_args} \"${a}\"" show_selections(args, sources, ufd_dev, UFD_SOURCES)
fi if not args['--force']:
done confirm_selections(args)
# Prep UFD
# Define the environment variables (and their defaults) that this script depends on if not args['--update']:
LOG_LEVEL="${LOG_LEVEL:-6}" # 7 = debug -> 0 = emergency print_info('Prep UFD')
NO_COLOR="${NO_COLOR:-}" # true = disable color. otherwise autodetected prep_device(ufd_dev, UFD_LABEL, use_mbr=args['--use-mbr'])
# Mount UFD
### Functions try_and_print(
############################################################################## indent=2,
message='Mounting UFD...',
function __b3bp_log () { function=mount,
local log_level="${1}" mount_source=find_first_partition(ufd_dev),
shift mount_point='/mnt/UFD',
read_write=True,
# shellcheck disable=SC2034 )
local color_debug="\x1b[35m"
# shellcheck disable=SC2034 # Remove Arch folder
local color_info="\x1b[32m" if args['--update']:
# shellcheck disable=SC2034 try_and_print(
local color_notice="\x1b[34m" indent=2,
# shellcheck disable=SC2034 message='Removing Linux...',
local color_warning="\x1b[33m" function=remove_arch,
# shellcheck disable=SC2034 )
local color_error="\x1b[31m"
# shellcheck disable=SC2034 # Copy sources
local color_critical="\x1b[1;31m" print_standard(' ')
# shellcheck disable=SC2034 print_info('Copy Sources')
local color_alert="\x1b[1;33;41m" for s_label, s_path in sources.items():
# shellcheck disable=SC2034 try_and_print(
local color_emergency="\x1b[1;4;5;33;41m" indent=2,
message='Copying {}...'.format(s_label),
local colorvar="color_${log_level}" function=copy_source,
source=s_path,
local color="${!colorvar:-${color_error}}" items=ITEMS[s_label],
local color_reset="\x1b[0m" overwrite=True,
)
if [[ "${NO_COLOR:-}" = "true" ]] || ( [[ "${TERM:-}" != *"256color"* ]] && [[ "${TERM:-}" != "xterm"* ]] && [[ "${TERM:-}" != "screen"* ]] ) || [[ ! -t 2 ]]; then
if [[ "${NO_COLOR:-}" != "false" ]]; then # Update boot entries
# Don't use colors on pipes or non-recognized terminals print_standard(' ')
color=""; color_reset="" print_info('Boot Setup')
fi try_and_print(
fi indent=2,
message='Updating boot entries...',
# all remaining arguments are to be printed function=update_boot_entries,
local log_line="" boot_entries=BOOT_ENTRIES,
boot_files=BOOT_FILES,
while IFS=$'\n' read -r log_line; do iso_label=ISO_LABEL,
echo -e "$(date -u +"%Y-%m-%d %H:%M:%S UTC") ${color}$(printf "[%9s]" "${log_level}")${color_reset} ${log_line}" 1>&2 ufd_label=UFD_LABEL,
done <<< "${@:-}" )
}
# Install syslinux (to partition)
function emergency () { __b3bp_log emergency "${@}"; exit 1; } try_and_print(
function alert () { [[ "${LOG_LEVEL:-0}" -ge 1 ]] && __b3bp_log alert "${@}"; true; } indent=2,
function critical () { [[ "${LOG_LEVEL:-0}" -ge 2 ]] && __b3bp_log critical "${@}"; true; } message='Syslinux (partition)...',
function error () { [[ "${LOG_LEVEL:-0}" -ge 3 ]] && __b3bp_log error "${@}"; true; } function=install_syslinux_to_partition,
function warning () { [[ "${LOG_LEVEL:-0}" -ge 4 ]] && __b3bp_log warning "${@}"; true; } partition=find_first_partition(ufd_dev),
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; } # Unmount UFD
try_and_print(
function help () { indent=2,
echo "" 1>&2 message='Unmounting UFD...',
echo " ${*}" 1>&2 function=unmount,
echo "" 1>&2 mount_point='/mnt/UFD',
echo " ${__usage:-No usage available}" 1>&2 )
echo "" 1>&2
# Install syslinux (to device)
if [[ "${__helptext:-}" ]]; then try_and_print(
echo " ${__helptext}" 1>&2 indent=2,
echo "" 1>&2 message='Syslinux (device)...',
fi function=install_syslinux_to_dev,
ufd_dev=ufd_dev,
exit 1 use_mbr=args['--use-mbr'],
} )
# Hide items
### Parse commandline options print_standard(' ')
############################################################################## print_info('Final Touches')
try_and_print(
# Commandline options. This defines the usage page, and is used to parse cli indent=2,
# opts & defaults from. The parsing is unforgiving so be precise in your syntax message='Hiding items...',
# - A short option must be preset for every long option; but every short option function=hide_items,
# need not have a long option ufd_dev=ufd_dev,
# - `--` is respected as the separator between options and arguments items=ITEMS_HIDDEN,
# - 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)
# Done
# shellcheck disable=SC2015 if not args['--force']:
[[ "${__usage+x}" ]] || read -r -d '' __usage <<-'EOF' || true # exits non-zero when EOF encountered print_standard('\nDone.')
OPTIONS: pause('Press Enter to exit...')
-u --ufd-device [arg] Device to which the kit will be applied exit_script()
-m --main-kit [arg] Path to the Main Kit except SystemExit as sys_exit:
-l --linux-iso [arg] Path to the Linux ISO exit_script(sys_exit.code)
-w --winpe-iso [arg] Path to the WinPE ISO except: # pylint: disable=bare-except
major_exception()
-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

View file

@ -79,21 +79,21 @@ if ($MyInvocation.InvocationName -ne ".") {
$Path = $Temp $Path = $Temp
# 7-Zip # 7-Zip
DownloadFile -Path $Path -Name "7z-installer.msi" -Url "https://www.7-zip.org/a/7z1805.msi" 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/7z1805-extra.7z" DownloadFile -Path $Path -Name "7z-extra.7z" -Url "https://www.7-zip.org/a/7z1900-extra.7z"
# ConEmu # 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 DownloadFile -Path $Path -Name "ConEmuPack.7z" -Url $Url
# Notepad++ # 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 DownloadFile -Path $Path -Name "npp.7z" -Url $Url
# Python # 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 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 DownloadFile -Path $Path -Name "python64.zip" -Url $Url
# Python: psutil # Python: psutil

View file

@ -131,25 +131,25 @@ if ($MyInvocation.InvocationName -ne ".") {
## Download Tools ## ## Download Tools ##
$ToolSources = @( $ToolSources = @(
# 7-Zip # 7-Zip
@("7z-installer.msi", "https://www.7-zip.org/a/7z1805.msi"), @("7z-installer.msi", "https://www.7-zip.org/a/7z1900.msi"),
@("7z-extra.7z", "https://www.7-zip.org/a/7z1805-extra.7z"), @("7z-extra.7z", "https://www.7-zip.org/a/7z1900-extra.7z"),
# Blue Screen View # Blue Screen View
@("bluescreenview32.zip", "http://www.nirsoft.net/utils/bluescreenview.zip"), @("bluescreenview32.zip", "http://www.nirsoft.net/utils/bluescreenview.zip"),
@("bluescreenview64.zip", "http://www.nirsoft.net/utils/bluescreenview-x64.zip"), @("bluescreenview64.zip", "http://www.nirsoft.net/utils/bluescreenview-x64.zip"),
# ConEmu # 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 # 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
@("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 # Killer Network Drivers
@( @(
"killerinf.zip", "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++ # Notepad++
@("npp_x86.7z", "https://notepad-plus-plus.org/repository/7.x/7.5.8/npp.7.5.8.bin.minimalist.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.5.8/npp.7.5.8.bin.minimalist.x64.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 # NT Password Editor
@("ntpwed.zip", "http://cdslow.org.ru/files/ntpwedit/ntpwed07.zip"), @("ntpwed.zip", "http://cdslow.org.ru/files/ntpwedit/ntpwed07.zip"),
# Prime95 # Prime95
@ -159,8 +159,8 @@ if ($MyInvocation.InvocationName -ne ".") {
@("produkey32.zip", "http://www.nirsoft.net/utils/produkey.zip"), @("produkey32.zip", "http://www.nirsoft.net/utils/produkey.zip"),
@("produkey64.zip", "http://www.nirsoft.net/utils/produkey-x64.zip"), @("produkey64.zip", "http://www.nirsoft.net/utils/produkey-x64.zip"),
# Python # Python
@("python32.zip", "https://www.python.org/ftp/python/3.7.0/python-3.7.0-embed-win32.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.0/python-3.7.0-embed-amd64.zip"), @("python64.zip", "https://www.python.org/ftp/python/3.7.2/python-3.7.2.post1-embed-amd64.zip"),
# Python: psutil # Python: psutil
@( @(
"psutil64.whl", "psutil64.whl",
@ -182,8 +182,8 @@ if ($MyInvocation.InvocationName -ne ".") {
@("vcredist_x86.exe", "https://aka.ms/vs/15/release/vc_redist.x86.exe"), @("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"), @("vcredist_x64.exe", "https://aka.ms/vs/15/release/vc_redist.x64.exe"),
# wimlib-imagex # wimlib-imagex
@("wimlib32.zip", "https://wimlib.net/downloads/wimlib-1.12.0-windows-i686-bin.zip"), @("wimlib32.zip", "https://wimlib.net/downloads/wimlib-1.13.0-windows-i686-bin.zip"),
@("wimlib64.zip", "https://wimlib.net/downloads/wimlib-1.12.0-windows-x86_64-bin.zip") @("wimlib64.zip", "https://wimlib.net/downloads/wimlib-1.13.0-windows-x86_64-bin.zip")
) )
foreach ($Tool in $ToolSources) { foreach ($Tool in $ToolSources) {
DownloadFile -Path $Temp -Name $Tool[0] -Url $Tool[1] DownloadFile -Path $Temp -Name $Tool[0] -Url $Tool[1]

View file

@ -4,8 +4,7 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.cleanup import * from functions.cleanup import *
from functions.data import * from functions.data import *
init_global_vars() init_global_vars()
@ -13,30 +12,32 @@ os.system('title {}: CBS Cleanup'.format(KIT_NAME_FULL))
set_log_file('CBS Cleanup.log') set_log_file('CBS Cleanup.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep
stay_awake() stay_awake()
clear_screen() clear_screen()
folder_path = r'{}\Backups'.format(KIT_NAME_SHORT) folder_path = r'{}\Backups'.format(KIT_NAME_SHORT)
dest = select_destination(folder_path=folder_path, dest = select_destination(folder_path=folder_path,
prompt='Which disk are we using for temp data and backup?') prompt='Which disk are we using for temp data and backup?')
# Show details # Show details
print_info('{}: CBS Cleanup Tool\n'.format(KIT_NAME_FULL)) print_info('{}: CBS Cleanup Tool\n'.format(KIT_NAME_FULL))
show_data('Backup / Temp path:', dest) show_data('Backup / Temp path:', dest)
print_standard('\n') print_standard('\n')
if (not ask('Proceed with CBS cleanup?')): if (not ask('Proceed with CBS cleanup?')):
abort() abort()
# Run Cleanup # Run Cleanup
try_and_print(message='Running cleanup...', function=cleanup_cbs, try_and_print(message='Running cleanup...', function=cleanup_cbs,
cs='Done', dest_folder=dest) cs='Done', dest_folder=dest)
# Done # Done
print_standard('\nDone.') print_standard('\nDone.')
pause("Press Enter to exit...") pause("Press Enter to exit...")
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,53 +4,54 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.repairs import * from functions.repairs import *
init_global_vars() init_global_vars()
os.system('title {}: Check Disk Tool'.format(KIT_NAME_FULL)) os.system('title {}: Check Disk Tool'.format(KIT_NAME_FULL))
set_log_file('Check Disk.log') set_log_file('Check Disk.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
stay_awake() stay_awake()
clear_screen() clear_screen()
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
}, },
'Warning': { 'Warning': {
'GenericRepair': 'Repaired', 'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS', 'UnsupportedOSError': 'Unsupported OS',
}} }}
options = [ options = [
{'Name': 'Run CHKDSK scan (read-only)', 'Repair': False}, {'Name': 'Run CHKDSK scan (read-only)', 'Repair': False},
{'Name': 'Schedule CHKDSK scan (offline repair)', 'Repair': True}] {'Name': 'Schedule CHKDSK scan (offline repair)', 'Repair': True}]
actions = [{'Name': 'Quit', 'Letter': 'Q'}] actions = [{'Name': 'Quit', 'Letter': 'Q'}]
selection = menu_select( selection = menu_select(
'{}: Check Disk Menu\n'.format(KIT_NAME_FULL), '{}: Check Disk Menu\n'.format(KIT_NAME_FULL),
main_entries=options, main_entries=options,
action_entries=actions) action_entries=actions)
print_info('{}: Check Disk Menu\n'.format(KIT_NAME_FULL)) print_info('{}: Check Disk Menu\n'.format(KIT_NAME_FULL))
if selection == 'Q': if selection == 'Q':
abort() abort()
elif selection.isnumeric(): elif selection.isnumeric():
repair = options[int(selection)-1]['Repair'] repair = options[int(selection)-1]['Repair']
if repair: if repair:
cs = 'Scheduled' cs = 'Scheduled'
else: else:
cs = 'CS' cs = 'No issues'
message = 'CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env']) message = 'CHKDSK ({SYSTEMDRIVE})...'.format(**global_vars['Env'])
try_and_print(message=message, function=run_chkdsk, try_and_print(message=message, function=run_chkdsk,
cs=cs, other_results=other_results, repair=repair) cs=cs, other_results=other_results, repair=repair)
else: else:
abort() abort()
# Done # Done
print_success('Done.') print_success('Done.')
pause("Press Enter to exit...") pause("Press Enter to exit...")
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() 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 ## Wizard Kit: ddrescue TUI Launcher
source launch-in-tmux
SESSION_NAME="ddrescue-tui" SESSION_NAME="ddrescue-tui"
WINDOW_NAME="GNU ddrescue TUI" WINDOW_NAME="ddrescue TUI"
MENU="ddrescue-tui-menu" TMUX_CMD="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" $*
launch_in_tmux "$@"

View file

@ -7,57 +7,58 @@ import sys
# Init # Init
sys.path.append(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from functions.ddrescue import * from functions.ddrescue import *
from functions.hw_diags import * from functions.hw_diags import *
init_global_vars() init_global_vars()
if __name__ == '__main__': if __name__ == '__main__':
try:
# Prep
clear_screen()
args = list(sys.argv)
run_mode = ''
source_path = None
dest_path = None
# Parse args
try: try:
# Prep script_name = os.path.basename(args.pop(0))
clear_screen() run_mode = str(args.pop(0)).lower()
args = list(sys.argv) source_path = args.pop(0)
run_mode = '' dest_path = args.pop(0)
source_path = None except IndexError:
dest_path = None # We'll set the missing paths later
pass
# Parse args # Show usage
try: if re.search(r'-+(h|help)', str(sys.argv), re.IGNORECASE):
script_name = os.path.basename(args.pop(0)) show_usage(script_name)
run_mode = str(args.pop(0)).lower() exit_script()
source_path = args.pop(0)
dest_path = args.pop(0)
except IndexError:
# We'll set the missing paths later
pass
# Show usage # Start cloning/imaging
if re.search(r'-+(h|help)', str(sys.argv), re.IGNORECASE): if run_mode in ('clone', 'image'):
show_usage(script_name) menu_ddrescue(source_path, dest_path, run_mode)
exit_script() else:
if not re.search(r'^-*(h|help\?)', run_mode, re.IGNORECASE):
print_error('Invalid mode.')
# Start cloning/imaging # Done
if run_mode in ('clone', 'image'): print_standard('\nDone.')
menu_ddrescue(source_path, dest_path, run_mode) pause("Press Enter to exit...")
else: tmux_switch_client()
if not re.search(r'^-*(h|help\?)', run_mode, re.IGNORECASE): exit_script()
print_error('Invalid mode.') except GenericAbort:
abort()
# Done except GenericError as ge:
print_standard('\nDone.') msg = 'Generic Error'
pause("Press Enter to exit...") if str(ge):
exit_script() msg = str(ge)
except GenericAbort: print_error(msg)
abort() abort()
except GenericError as ge: except SystemExit as sys_exit:
msg = 'Generic Error' tmux_switch_client()
if str(ge): exit_script(sys_exit.code)
msg = str(ge) except:
print_error(msg) major_exception()
abort()
except SystemExit:
pass
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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.repairs import * from functions.repairs import *
init_global_vars() init_global_vars()
os.system('title {}: DISM helper Tool'.format(KIT_NAME_FULL)) os.system('title {}: DISM helper Tool'.format(KIT_NAME_FULL))
set_log_file('DISM Helper.log') set_log_file('DISM Helper.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
stay_awake() stay_awake()
clear_screen() clear_screen()
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
}, },
'Warning': { 'Warning': {
'GenericRepair': 'Repaired', 'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS', 'UnsupportedOSError': 'Unsupported OS',
}} }}
disabled = bool(global_vars['OS']['Version'] not in ('8', '8.1', '10')) disabled = bool(global_vars['OS']['Version'] not in ('8', '8.1', '10'))
options = [ options = [
{'Name': 'Check Health', 'Repair': False, 'Disabled': disabled}, {'Name': 'Check Health', 'Repair': False, 'Disabled': disabled},
{'Name': 'Restore Health', 'Repair': True, 'Disabled': disabled}] {'Name': 'Restore Health', 'Repair': True, 'Disabled': disabled}]
actions = [{'Name': 'Quit', 'Letter': 'Q'}] actions = [{'Name': 'Quit', 'Letter': 'Q'}]
selection = menu_select( selection = menu_select(
'{}: DISM Menu\n'.format(KIT_NAME_FULL), '{}: DISM Menu\n'.format(KIT_NAME_FULL),
main_entries=options, main_entries=options,
action_entries=actions) action_entries=actions)
print_info('{}: DISM Menu\n'.format(KIT_NAME_FULL)) print_info('{}: DISM Menu\n'.format(KIT_NAME_FULL))
if selection == 'Q': if selection == 'Q':
abort() abort()
elif selection.isnumeric(): elif selection.isnumeric():
repair = options[int(selection)-1]['Repair'] repair = options[int(selection)-1]['Repair']
if repair: if repair:
message='DISM RestoreHealth...' message='DISM RestoreHealth...'
else: else:
message='DISM ScanHealth...' message='DISM ScanHealth...'
try_and_print(message=message, function=run_dism, try_and_print(message=message, function=run_dism,
cs='No corruption', ns='Corruption detected', cs='No corruption', ns='Corruption detected',
other_results=other_results, repair=repair) other_results=other_results, repair=repair)
else: else:
abort() abort()
# Done # Done
print_success('Done.') print_success('Done.')
pause("Press Enter to exit...") pause("Press Enter to exit...")
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -6,61 +6,68 @@ from borrowed import acpi
from functions.common import * from functions.common import *
from os import environ from os import environ
# Variables
# STATIC VARIABLES
SLMGR = r'{}\System32\slmgr.vbs'.format(environ.get('SYSTEMROOT')) SLMGR = r'{}\System32\slmgr.vbs'.format(environ.get('SYSTEMROOT'))
def activate_with_bios(): def activate_with_bios():
"""Attempt to activate Windows with a key stored in the BIOS.""" """Attempt to activate Windows with a key stored in the BIOS."""
# Code borrowed from https://github.com/aeruder/get_win8key # Code borrowed from https://github.com/aeruder/get_win8key
##################################################### #####################################################
#script to query windows 8.x OEM key from PC firmware #script to query windows 8.x OEM key from PC firmware
#ACPI -> table MSDM -> raw content -> byte offset 56 to end #ACPI -> table MSDM -> raw content -> byte offset 56 to end
#ck, 03-Jan-2014 (christian@korneck.de) #ck, 03-Jan-2014 (christian@korneck.de)
##################################################### #####################################################
bios_key = None bios_key = None
table = b"MSDM" table = b"MSDM"
if acpi.FindAcpiTable(table) is True: if acpi.FindAcpiTable(table) is True:
rawtable = acpi.GetAcpiTable(table) rawtable = acpi.GetAcpiTable(table)
#http://msdn.microsoft.com/library/windows/hardware/hh673514 #http://msdn.microsoft.com/library/windows/hardware/hh673514
#byte offset 36 from beginning \ #byte offset 36 from beginning \
# = Microsoft 'software licensing data structure' \ # = Microsoft 'software licensing data structure' \
# / 36 + 20 bytes offset from beginning = Win Key # / 36 + 20 bytes offset from beginning = Win Key
bios_key = rawtable[56:len(rawtable)].decode("utf-8") bios_key = rawtable[56:len(rawtable)].decode("utf-8")
if bios_key is None: if bios_key is None:
raise BIOSKeyNotFoundError raise BIOSKeyNotFoundError
# Install Key # Install Key
cmd = ['cscript', '//nologo', SLMGR, '/ipk', bios_key] cmd = ['cscript', '//nologo', SLMGR, '/ipk', bios_key]
subprocess.run(cmd, check=False) subprocess.run(cmd, check=False)
sleep(5) sleep(5)
# Attempt activation # Attempt activation
cmd = ['cscript', '//nologo', SLMGR, '/ato'] cmd = ['cscript', '//nologo', SLMGR, '/ato']
subprocess.run(cmd, check=False) subprocess.run(cmd, check=False)
sleep(5) 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(): def get_activation_string():
"""Get activation status, returns str.""" """Get activation status, returns str."""
act_str = subprocess.run( act_str = subprocess.run(
['cscript', '//nologo', SLMGR, '/xpr'], check=False, ['cscript', '//nologo', SLMGR, '/xpr'], check=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
act_str = act_str.stdout.decode() act_str = act_str.stdout.decode()
act_str = act_str.splitlines() act_str = act_str.splitlines()
act_str = act_str[1].strip() act_str = act_str[1].strip()
return act_str return act_str
def windows_is_activated(): def windows_is_activated():
"""Check if Windows is activated via slmgr.vbs and return bool.""" """Check if Windows is activated via slmgr.vbs and return bool."""
activation_string = subprocess.run( activation_string = subprocess.run(
['cscript', '//nologo', SLMGR, '/xpr'], check=False, ['cscript', '//nologo', SLMGR, '/xpr'], check=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=subprocess.PIPE, stderr=subprocess.PIPE)
activation_string = activation_string.stdout.decode() 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__': 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 * from functions.disk import *
# Regex # Regex
REGEX_BAD_PATH_NAMES = re.compile( REGEX_BAD_PATH_NAMES = re.compile(
r'([<>:"/\|\?\*]' r'([<>:"/\|\?\*]'
r'|^(CON|PRN|AUX|NUL|COM\d*|LPT\d*)$)' r'|^(CON|PRN|AUX|NUL|COM\d*|LPT\d*)$)'
r'|^\s+' r'|^\s+'
r'|[\s\.]+$', r'|[\s\.]+$',
re.IGNORECASE) re.IGNORECASE)
def backup_partition(disk, par): def backup_partition(disk, par):
"""Create a backup image of a partition.""" """Create a backup image of a partition."""
if par.get('Image Exists', False) or par['Number'] in disk['Bad Partitions']: if (par.get('Image Exists', False)
raise GenericAbort 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): def fix_path(path):
"""Replace invalid filename characters with underscores.""" """Replace invalid filename characters with underscores."""
local_drive = path[1:2] == ':' local_drive = path[1:2] == ':'
new_path = REGEX_BAD_PATH_NAMES.sub('_', path) new_path = REGEX_BAD_PATH_NAMES.sub('_', path)
if local_drive: if local_drive:
new_path = '{}:{}'.format(new_path[0:1], new_path[2:]) new_path = '{}:{}'.format(new_path[0:1], new_path[2:])
return new_path return new_path
def get_volume_display_name(mountpoint): def get_volume_display_name(mountpoint):
"""Get display name from volume mountpoint and label, returns str.""" """Get display name from volume mountpoint and label, returns str."""
name = mountpoint name = mountpoint
try: try:
kernel32 = ctypes.windll.kernel32 kernel32 = ctypes.windll.kernel32
vol_name_buffer = ctypes.create_unicode_buffer(1024) vol_name_buffer = ctypes.create_unicode_buffer(1024)
fs_name_buffer = ctypes.create_unicode_buffer(1024) fs_name_buffer = ctypes.create_unicode_buffer(1024)
serial_number = None serial_number = None
max_component_length = None max_component_length = None
file_system_flags = None file_system_flags = None
vol_info = kernel32.GetVolumeInformationW( vol_info = kernel32.GetVolumeInformationW(
ctypes.c_wchar_p(mountpoint), ctypes.c_wchar_p(mountpoint),
vol_name_buffer, vol_name_buffer,
ctypes.sizeof(vol_name_buffer), ctypes.sizeof(vol_name_buffer),
serial_number, serial_number,
max_component_length, max_component_length,
file_system_flags, file_system_flags,
fs_name_buffer, fs_name_buffer,
ctypes.sizeof(fs_name_buffer) ctypes.sizeof(fs_name_buffer)
) )
name = '{} "{}"'.format(name, vol_name_buffer.value) name = '{} "{}"'.format(name, vol_name_buffer.value)
except: except:
pass pass
return name
return name
def prep_disk_for_backup(destination, disk, backup_prefix): 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, This includes partitions that can't be backed up,
whether backups already exist on the BACKUP_SERVER, whether backups already exist on the BACKUP_SERVER,
partition names/sizes/used space, etc.""" partition names/sizes/used space, etc."""
disk['Clobber Risk'] = [] disk['Clobber Risk'] = []
width = len(str(len(disk['Partitions']))) width = len(str(len(disk['Partitions'])))
# Get partition totals # Get partition totals
disk['Bad Partitions'] = [par['Number'] for par in disk['Partitions'] disk['Bad Partitions'] = [par['Number'] for par in disk['Partitions']
if is_bad_partition(par)] if is_bad_partition(par)]
num_valid_partitions = len(disk['Partitions']) - len(disk['Bad Partitions']) num_valid_partitions = len(disk['Partitions']) - len(disk['Bad Partitions'])
disk['Valid Partitions'] = num_valid_partitions disk['Valid Partitions'] = num_valid_partitions
if disk['Valid Partitions'] <= 0: if disk['Valid Partitions'] <= 0:
print_error('ERROR: No partitions can be backed up for this disk') print_error('ERROR: No partitions can be backed up for this disk')
raise GenericAbort raise GenericAbort
# Prep partitions # Prep partitions
for par in disk['Partitions']: for par in disk['Partitions']:
display = '{size} {fs}'.format( display = '{size} {fs}'.format(
num = par['Number'], num = par['Number'],
width = width, width = width,
size = par['Size'], size = par['Size'],
fs = par['FileSystem']) fs = par['FileSystem'])
if par['Number'] in disk['Bad Partitions']: if par['Number'] in disk['Bad Partitions']:
# Set display string using partition description & OS type # Set display string using partition description & OS type
display = '* {display}\t\t{q}{name}{q}\t{desc} ({os})'.format( display = '* {display}\t\t{q}{name}{q}\t{desc} ({os})'.format(
display = display, display = display,
q = '"' if par['Name'] != '' else '', q = '"' if par['Name'] != '' else '',
name = par['Name'], name = par['Name'],
desc = par['Description'], desc = par['Description'],
os = par['OS']) os = par['OS'])
else: else:
# Update info for WIM capturing # Update info for WIM capturing
par['Image Name'] = par['Name'] if par['Name'] else 'Unknown' par['Image Name'] = par['Name'] if par['Name'] else 'Unknown'
if 'IP' in destination: if 'IP' in destination:
par['Image Path'] = r'\\{}\{}\{}'.format( par['Image Path'] = r'\\{}\{}\{}'.format(
destination['IP'], destination['Share'], backup_prefix) destination['IP'], destination['Share'], backup_prefix)
else: else:
par['Image Path'] = r'{}:\{}'.format( par['Image Path'] = r'{}:\{}'.format(
destination['Letter'], backup_prefix) destination['Letter'], backup_prefix)
par['Image Path'] += r'\{}_{}.wim'.format( par['Image Path'] += r'\{}_{}.wim'.format(
par['Number'], par['Image Name']) par['Number'], par['Image Name'])
par['Image Path'] = fix_path(par['Image Path']) par['Image Path'] = fix_path(par['Image Path'])
# Check for existing backups # Check for existing backups
par['Image Exists'] = os.path.exists(par['Image Path']) par['Image Exists'] = os.path.exists(par['Image Path'])
if par['Image Exists']: if par['Image Exists']:
disk['Clobber Risk'].append(par['Number']) disk['Clobber Risk'].append(par['Number'])
display = '+ {}'.format(display) display = '+ {}'.format(display)
else: else:
display = ' {}'.format(display) display = ' {}'.format(display)
# Append rest of Display String for valid/clobber partitions # Append rest of Display String for valid/clobber partitions
display += ' (Used: {used})\t{q}{name}{q}'.format( display += ' (Used: {used})\t{q}{name}{q}'.format(
used = par['Used Space'], used = par['Used Space'],
q = '"' if par['Name'] != '' else '', q = '"' if par['Name'] != '' else '',
name = par['Name']) name = par['Name'])
# For all partitions # For all partitions
par['Display String'] = display 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): def select_backup_destination(auto_select=True):
"""Select a backup destination from a menu, returns server dict.""" """Select a backup destination from a menu, returns server dict."""
destinations = [s for s in BACKUP_SERVERS if s['Mounted']] destinations = [s for s in BACKUP_SERVERS if s['Mounted']]
actions = [ actions = [
{'Name': 'Main Menu', 'Letter': 'M'}, {'Name': 'Main Menu', 'Letter': 'M'},
] ]
# Add local disks # Add local disks
for d in psutil.disk_partitions(): for d in psutil.disk_partitions():
if re.search(r'^{}'.format(global_vars['Env']['SYSTEMDRIVE']), d.mountpoint, re.IGNORECASE): if re.search(
# Skip current OS drive r'^{}'.format(global_vars['Env']['SYSTEMDRIVE']),
pass d.mountpoint,
elif 'fixed' in d.opts: re.IGNORECASE):
# Skip DVD, etc # Skip current OS drive
destinations.append({ pass
'Name': 'Local Disk - {}'.format( elif 'fixed' in d.opts:
get_volume_display_name(d.mountpoint)), # Skip DVD, etc
'Letter': re.sub(r'^(\w):\\.*$', r'\1', d.mountpoint), destinations.append({
}) 'Name': 'Local Disk - {}'.format(
get_volume_display_name(d.mountpoint)),
'Letter': re.sub(r'^(\w):\\.*$', r'\1', d.mountpoint),
})
# Size check # Size check
for dest in destinations: for dest in destinations:
if 'IP' in dest: if 'IP' in dest:
dest['Usage'] = shutil.disk_usage(r'\\{IP}\{Share}'.format(**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
else: 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): def verify_wim_backup(partition):
"""Verify WIM integrity.""" """Verify WIM integrity."""
if not os.path.exists(partition['Image Path']): if not os.path.exists(partition['Image Path']):
raise PathNotFoundError raise PathNotFoundError
cmd = [ cmd = [
global_vars['Tools']['wimlib-imagex'], global_vars['Tools']['wimlib-imagex'],
'verify', 'verify',
partition['Image Path'], partition['Image Path'],
'--nocheck', '--nocheck',
] ]
run_program(cmd) run_program(cmd)
if __name__ == '__main__': 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 # Wizard Kit: Functions - Browsers
from functions.common import * from functions.common import *
from operator import itemgetter from operator import itemgetter
from settings.browsers import *
# Define other_results for later try_and_print # Define other_results for later try_and_print
browser_data = {} browser_data = {}
other_results = { other_results = {
'Error': { 'Error': {
'MultipleInstallationsError': 'Multiple installations detected', 'MultipleInstallationsError': 'Multiple installations detected',
}, },
'Warning': { 'Warning': {
'NotInstalledError': 'Not installed', 'NotInstalledError': 'Not installed',
'NoProfilesError': 'No profiles found', '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(): def archive_all_users():
"""Create backups for all browsers for all users.""" """Create backups for all browsers for all users."""
users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE']) users_root = r'{}\Users'.format(global_vars['Env']['SYSTEMDRIVE'])
user_envs = [] user_envs = []
# Build list of valid users # Build list of valid users
for user_name in os.listdir(users_root): for user_name in os.listdir(users_root):
valid_user = True valid_user = True
if user_name in ('Default', 'Default User'): if user_name in ('Default', 'Default User'):
# Skip default users # Skip default users
continue continue
user_path = os.path.join(users_root, user_name) user_path = os.path.join(users_root, user_name)
appdata_local = os.path.join(user_path, r'AppData\Local') appdata_local = os.path.join(user_path, r'AppData\Local')
appdata_roaming = os.path.join(user_path, r'AppData\Roaming') appdata_roaming = os.path.join(user_path, r'AppData\Roaming')
valid_user &= os.path.exists(appdata_local) valid_user = valid_user and os.path.exists(appdata_local)
valid_user &= os.path.exists(appdata_roaming) valid_user = valid_user and os.path.exists(appdata_roaming)
if valid_user: if valid_user:
user_envs.append({ user_envs.append({
'USERNAME': user_name, 'USERNAME': user_name,
'USERPROFILE': user_path, 'USERPROFILE': user_path,
'APPDATA': appdata_roaming, 'APPDATA': appdata_roaming,
'LOCALAPPDATA': appdata_local}) 'LOCALAPPDATA': appdata_local})
# Backup browsers for all valid users # Backup browsers for all valid users
print_info('Backing up browsers') print_info('Backing up browsers')
for fake_env in sorted(user_envs, key=itemgetter('USERPROFILE')): for fake_env in sorted(user_envs, key=itemgetter('USERPROFILE')):
print_standard(' {}'.format(fake_env['USERNAME'])) print_standard(' {}'.format(fake_env['USERNAME']))
for b_k, b_v in sorted(SUPPORTED_BROWSERS.items()): for b_k, b_v in sorted(SUPPORTED_BROWSERS.items()):
if b_k == 'Mozilla Firefox Dev': if b_k == 'Mozilla Firefox Dev':
continue continue
source_path = b_v['user_data_path'].format(**fake_env) source_path = b_v['user_data_path'].format(**fake_env)
if not os.path.exists(source_path): if not os.path.exists(source_path):
continue continue
source_items = source_path + '*' source_items = source_path + '*'
archive_path = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format( archive_path = r'{BackupDir}\Browsers ({USERNAME})\{Date}'.format(
**global_vars, **fake_env) **global_vars, **fake_env)
os.makedirs(archive_path, exist_ok=True) os.makedirs(archive_path, exist_ok=True)
archive_path += r'\{}.7z'.format(b_k) archive_path += r'\{}.7z'.format(b_k)
cmd = [ 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 = [
global_vars['Tools']['SevenZip'], global_vars['Tools']['SevenZip'],
'a', '-aoa', '-bso0', '-bse0', '-mx=1', 'a', '-aoa', '-bso0', '-bse0', '-mx=1',
'-mhe=on', '-p{}'.format(ARCHIVE_PASSWORD), archive_path, source_items]
archive, source] try_and_print(message='{}...'.format(b_k),
run_program(cmd) 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(): def backup_browsers():
"""Create backup of all detected browser profiles.""" """Create backup of all detected browser profiles."""
for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]: for name in [k for k, v in sorted(browser_data.items()) if v['profiles']]:
try_and_print(message='{}...'.format(name), try_and_print(message='{}...'.format(name),
function=archive_browser, name=name) function=archive_browser, name=name)
def clean_chromium_profile(profile): def clean_chromium_profile(profile):
"""Renames profile, creates a new folder, and copies the user data to it.""" """Recreate profile with only the essential user data.
if profile is None:
raise Exception This is done by renaming the existing profile, creating a new folder
backup_path = '{path}_{Date}.bak'.format( with the original name, then copying the essential files from the
path=profile['path'], **global_vars) backup folder. This way the original state is preserved in case
backup_path = non_clobber_rename(backup_path) something goes wrong.
shutil.move(profile['path'], backup_path) """
os.makedirs(profile['path'], exist_ok=True) 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): 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.""" NOTE: kwargs set but unused as a workaround."""
kill_process('iexplore.exe') kill_process('iexplore.exe')
run_program(['rundll32.exe', 'inetcpl.cpl,ResetIEtoDefaults'], check=False) run_program(['rundll32.exe', 'inetcpl.cpl,ResetIEtoDefaults'], check=False)
key = r'Software\Microsoft\Internet Explorer\Main' 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): def clean_mozilla_profile(profile):
"""Renames profile, creates a new folder, and copies the user data to it.""" """Recreate profile with only the essential user data.
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 This is done by renaming the existing profile, creating a new folder
for entry in os.scandir(backup_path): with the original name, then copying the essential files from the
if REGEX_MOZILLA.search(entry.name): backup folder. This way the original state is preserved in case
if entry.is_dir(): something goes wrong.
shutil.copytree(entry.path, r'{}\{}'.format( """
profile['path'], entry.name)) if profile is None:
else: raise Exception
shutil.copy(entry.path, r'{}\{}'.format( backup_path = '{path}_{Date}.bak'.format(
profile['path'], entry.name)) 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): def get_browser_details(name):
"""Get installation status and profile details for all supported browsers.""" """Get installation and profile details for all supported browsers."""
browser = SUPPORTED_BROWSERS[name].copy() browser = SUPPORTED_BROWSERS[name].copy()
# Update user_data_path # Update user_data_path
browser['user_data_path'] = browser['user_data_path'].format( browser['user_data_path'] = browser['user_data_path'].format(
**global_vars['Env']) **global_vars['Env'])
# Find executable (if multiple files are found, the last one is used) # Find executable (if multiple files are found, the last one is used)
exe_path = None exe_path = None
num_installs = 0 num_installs = 0
for install_path in ['LOCALAPPDATA', 'PROGRAMFILES(X86)', 'PROGRAMFILES']: for install_path in ['LOCALAPPDATA', 'PROGRAMFILES(X86)', 'PROGRAMFILES']:
test_path = r'{install_path}\{rel_install_path}\{exe_name}'.format( test_path = r'{install_path}\{rel_install_path}\{exe_name}'.format(
install_path = global_vars['Env'].get(install_path, ''), install_path = global_vars['Env'].get(install_path, ''),
**browser) **browser)
if os.path.exists(test_path): if os.path.exists(test_path):
num_installs += 1 num_installs += 1
exe_path = test_path exe_path = test_path
# Find profile(s) # Find profile(s)
profiles = [] profiles = []
if browser['base'] == 'ie': if browser['base'] == 'ie':
profiles.append({'name': 'Default', 'path': None}) profiles.append({'name': 'Default', 'path': None})
elif 'Google Chrome' in name: elif 'Google Chrome' in name:
profiles.extend( profiles.extend(
get_chromium_profiles( get_chromium_profiles(
search_path=browser['user_data_path'])) search_path=browser['user_data_path']))
elif browser['base'] == 'mozilla': elif browser['base'] == 'mozilla':
dev = 'Dev' in name dev = 'Dev' in name
profiles.extend( profiles.extend(
get_mozilla_profiles( get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev)) search_path=browser['user_data_path'], dev=dev))
if exe_path and not dev and len(profiles) == 0: if exe_path and not dev and len(profiles) == 0:
# e.g. If Firefox is installed but no profiles were found. # e.g. If Firefox is installed but no profiles were found.
## Rename profiles.ini and create a new default profile ## Rename profiles.ini and create a new default profile
profiles_ini_path = browser['user_data_path'].replace( profiles_ini_path = browser['user_data_path'].replace(
'Profiles', 'profiles.ini') 'Profiles', 'profiles.ini')
if os.path.exists(profiles_ini_path): if os.path.exists(profiles_ini_path):
backup_path = '{path}_{Date}.bak'.format( backup_path = '{path}_{Date}.bak'.format(
path=profiles_ini_path, **global_vars) path=profiles_ini_path, **global_vars)
backup_path = non_clobber_rename(backup_path) backup_path = non_clobber_rename(backup_path)
shutil.move(profiles_ini_path, backup_path) shutil.move(profiles_ini_path, backup_path)
run_program([exe_path, '-createprofile', 'default'], check=False) run_program([exe_path, '-createprofile', 'default'], check=False)
profiles.extend( profiles.extend(
get_mozilla_profiles( get_mozilla_profiles(
search_path=browser['user_data_path'], dev=dev)) search_path=browser['user_data_path'], dev=dev))
elif 'Opera' in name: elif 'Opera' in name:
if os.path.exists(browser['user_data_path']): if os.path.exists(browser['user_data_path']):
profiles.append( profiles.append(
{'name': 'Default', 'path': browser['user_data_path']}) {'name': 'Default', 'path': browser['user_data_path']})
# Get homepages # Get homepages
if browser['base'] == 'ie': if browser['base'] == 'ie':
# IE is set to only have one profile above # IE is set to only have one profile above
profiles[0]['homepages'] = get_ie_homepages() profiles[0]['homepages'] = get_ie_homepages()
elif browser['base'] == 'mozilla': elif browser['base'] == 'mozilla':
for profile in profiles: for profile in profiles:
prefs_path = r'{path}\prefs.js'.format(**profile) prefs_path = r'{path}\prefs.js'.format(**profile)
profile['homepages'] = get_mozilla_homepages(prefs_path=prefs_path) profile['homepages'] = get_mozilla_homepages(prefs_path=prefs_path)
# Add to browser_data # Add to browser_data
browser_data[name] = browser browser_data[name] = browser
browser_data[name].update({ browser_data[name].update({
'exe_path': exe_path, 'exe_path': exe_path,
'profiles': profiles, '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): def get_chromium_profiles(search_path):
"""Find any chromium-style profiles and return as a list of dicts.""" """Find any chromium-style profiles and return as a list of dicts."""
profiles = [] profiles = []
try: try:
for entry in os.scandir(search_path): for entry in os.scandir(search_path):
if entry.is_dir() and REGEX_CHROMIUM_PROFILE.search(entry.name): if entry.is_dir() and REGEX_CHROMIUM_PROFILE.search(entry.name):
profiles.append(entry) profiles.append(entry)
REGEX_PROFILE_BACKUP = r'\.\w+bak.*' REGEX_PROFILE_BACKUP = r'\.\w+bak.*'
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)] profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts # Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles] profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception: except Exception:
pass pass
return profiles
return profiles
def get_ie_homepages(): def get_ie_homepages():
"""Read homepages from the registry and return as a list.""" """Read homepages from the registry and return as a list."""
homepages = [] homepages = []
main_page = '' main_page = ''
extra_pages = [] extra_pages = []
key = r'Software\Microsoft\Internet Explorer\Main' key = r'Software\Microsoft\Internet Explorer\Main'
with winreg.OpenKey(HKCU, key) as _key: with winreg.OpenKey(HKCU, key) as _key:
try: try:
main_page = winreg.QueryValueEx(_key, 'Start Page')[0] main_page = winreg.QueryValueEx(_key, 'Start Page')[0]
except FileNotFoundError: except FileNotFoundError:
pass pass
try: try:
extra_pages = winreg.QueryValueEx(_key, 'Secondary Start Pages')[0] extra_pages = winreg.QueryValueEx(_key, 'Secondary Start Pages')[0]
except FileNotFoundError: except FileNotFoundError:
pass pass
if main_page != '': if main_page != '':
homepages.append(main_page) homepages.append(main_page)
if len(extra_pages) > 0: if len(extra_pages) > 0:
homepages.extend(extra_pages) 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): def get_mozilla_homepages(prefs_path):
"""Read homepages from prefs.js and return as a list.""" """Read homepages from prefs.js and return as a list."""
homepages = [] homepages = []
try: try:
with open(prefs_path, 'r') as f: with open(prefs_path, 'r') as f:
search = re.search( search = re.search(
r'browser\.startup\.homepage", "([^"]*)"', r'browser\.startup\.homepage", "([^"]*)"',
f.read(), re.IGNORECASE) f.read(), re.IGNORECASE)
if search: if search:
homepages = search.group(1).split('|') homepages = search.group(1).split('|')
except Exception: except Exception:
pass pass
return homepages
return homepages
def get_mozilla_profiles(search_path, dev=False): def get_mozilla_profiles(search_path, dev=False):
"""Find any mozilla-style profiles and return as a list of dicts.""" """Find any mozilla-style profiles and return as a list of dicts."""
profiles = [] profiles = []
try: try:
for entry in os.scandir(search_path): for entry in os.scandir(search_path):
if entry.is_dir(): if entry.is_dir():
if 'dev-edition' in entry.name: if 'dev-edition' in entry.name:
# NOTE: Not always present which can lead # NOTE: Not always present which can lead
# to Dev profiles being marked as non-Dev # to Dev profiles being marked as non-Dev
## NOTE 2: It is possible that a non-Dev profile ## NOTE 2: It is possible that a non-Dev profile
## to be created with 'dev-edition' in the name. ## to be created with 'dev-edition' in the name.
## (It wouldn't make sense, but possible) ## (It wouldn't make sense, but possible)
if dev: if dev:
profiles.append(entry) profiles.append(entry)
elif not dev: elif not dev:
profiles.append(entry) profiles.append(entry)
profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)] profiles = [p for p in profiles if not REGEX_BACKUP.search(p.name)]
# Convert os.DirEntries to dicts # Convert os.DirEntries to dicts
profiles = [{'name': p.name, 'path': p.path} for p in profiles] profiles = [{'name': p.name, 'path': p.path} for p in profiles]
except Exception: except Exception:
pass pass
return profiles
return profiles
def install_adblock(indent=8, width=32, just_firefox=False): def install_adblock(indent=8, width=32, just_firefox=False):
"""Install adblock for all supported browsers.""" """Install adblock for all supported browsers."""
for browser in sorted(browser_data): for browser in sorted(browser_data):
if just_firefox and browser_data[browser]['base'] != 'mozilla': if just_firefox and browser_data[browser]['base'] != 'mozilla':
continue continue
exe_path = browser_data[browser].get('exe_path', None) exe_path = browser_data[browser].get('exe_path', None)
function=run_program if not exe_path:
if not exe_path: if browser_data[browser]['profiles']:
if browser_data[browser]['profiles']: print_standard(
print_standard( '{indent}{browser:<{width}}'.format(
'{indent}{browser:<{width}}'.format( indent=' '*indent, width=width, browser=browser+'...'),
indent=' '*indent, width=width, browser=browser+'...'), end='', flush=True)
end='', flush=True) print_warning('Profile(s) detected but browser not installed',
print_warning('Profile(s) detected but browser not installed', timestamp=False)
timestamp=False) else:
else: # Only warn if profile(s) are detected.
# Only warn if profile(s) are detected. pass
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: else:
# Set urls to open urls.append(UBO_CHROME)
urls = [] urls.append(UBO_EXTRA_CHROME)
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: elif browser_data[browser]['base'] == 'mozilla':
urls = ['chrome://extensions'] # Check for system extensions
elif 'Opera' in browser: try:
urls.append(UBO_OPERA) with winreg.OpenKey(HKLM, UBO_MOZILLA_REG) as key:
else: winreg.QueryValueEx(key, UBO_MOZILLA_REG_NAME)
urls.append(UBO_CHROME) except FileNotFoundError:
urls.append(UBO_EXTRA_CHROME) urls = [UBO_MOZILLA]
else:
if os.path.exists(UBO_MOZZILA_PATH):
urls = ['about:addons']
else:
urls = [UBO_MOZILLA]
elif browser_data[browser]['base'] == 'mozilla': elif browser_data[browser]['base'] == 'ie':
# Check for system extensions urls.append(IE_GALLERY)
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': # By using check=False we're skipping any return codes so
urls.append(IE_GALLERY) # it should only fail if the program can't be run
function=popen_program # (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): 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']]: # All other browsers
# Skip Chromium-based browsers print_info('{indent}{browser:<{width}}'.format(
if browser_data[browser]['base'] == 'chromium': indent=' '*indent, width=width, browser=browser+'...'))
print_info( for profile in browser_data[browser].get('profiles', []):
'{indent}{browser:<{width}}'.format( name = profile.get('name', '?')
indent=' '*indent, width=width, browser=browser+'...'), homepages = profile.get('homepages', [])
end='', flush=True) if len(homepages) == 0:
print_warning('Not implemented', timestamp=False) print_standard(
continue '{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): def reset_browsers(indent=8, width=32):
"""Reset all detected browsers to safe defaults.""" """Reset all detected browsers to safe defaults."""
for browser in [k for k, v in sorted(browser_data.items()) if v['profiles']]: browser_list = [k for k, v in sorted(browser_data.items()) if v['profiles']]
print_info('{indent}{name}'.format(indent=' '*indent, name=browser)) for browser in browser_list:
for profile in browser_data[browser]['profiles']: print_info('{indent}{name}'.format(indent=' '*indent, name=browser))
if browser_data[browser]['base'] == 'chromium': for profile in browser_data[browser]['profiles']:
function = clean_chromium_profile if browser_data[browser]['base'] == 'chromium':
elif browser_data[browser]['base'] == 'ie': function = clean_chromium_profile
function = clean_internet_explorer elif browser_data[browser]['base'] == 'ie':
elif browser_data[browser]['base'] == 'mozilla': function = clean_internet_explorer
function = clean_mozilla_profile elif browser_data[browser]['base'] == 'mozilla':
try_and_print( function = clean_mozilla_profile
message='{}...'.format(profile['name']), try_and_print(
indent=indent, width=width, function=function, message='{}...'.format(profile['name']),
other_results=other_results, profile=profile) 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__': 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(): def cleanup_adwcleaner():
"""Move AdwCleaner folders into the ClientDir.""" """Move AdwCleaner folders into the ClientDir."""
source_path = r'{SYSTEMDRIVE}\AdwCleaner'.format(**global_vars['Env']) source_path = r'{SYSTEMDRIVE}\AdwCleaner'.format(**global_vars['Env'])
source_quarantine = r'{}\Quarantine'.format(source_path) source_quarantine = r'{}\Quarantine'.format(source_path)
# Quarantine # Quarantine
if os.path.exists(source_quarantine): if os.path.exists(source_quarantine):
os.makedirs(global_vars['QuarantineDir'], exist_ok=True) os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
dest_name = r'{QuarantineDir}\AdwCleaner_{Date-Time}'.format( dest_name = r'{QuarantineDir}\AdwCleaner_{Date-Time}'.format(
**global_vars) **global_vars)
dest_name = non_clobber_rename(dest_name) dest_name = non_clobber_rename(dest_name)
shutil.move(source_quarantine, dest_name) shutil.move(source_quarantine, dest_name)
# Delete source folder if empty # Delete source folder if empty
delete_empty_folders(source_path) 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): 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 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. 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, 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 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. 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) backup_folder = r'{dest_folder}\CbsFix'.format(dest_folder=dest_folder)
temp_folder = r'{backup_folder}\Temp'.format(backup_folder=backup_folder) temp_folder = r'{backup_folder}\Temp'.format(backup_folder=backup_folder)
os.makedirs(backup_folder, exist_ok=True) os.makedirs(backup_folder, exist_ok=True)
os.makedirs(temp_folder, exist_ok=True) os.makedirs(temp_folder, exist_ok=True)
# Move files into temp folder # Move files into temp folder
cbs_path = r'{SYSTEMROOT}\Logs\CBS'.format(**global_vars['Env']) cbs_path = r'{SYSTEMROOT}\Logs\CBS'.format(**global_vars['Env'])
for entry in os.scandir(cbs_path): for entry in os.scandir(cbs_path):
# CbsPersist files # CbsPersist files
if entry.name.lower().startswith('cbspersist'): if entry.name.lower().startswith('cbspersist'):
dest_name = r'{}\{}'.format(temp_folder, entry.name) dest_name = r'{}\{}'.format(temp_folder, entry.name)
dest_name = non_clobber_rename(dest_name) dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, dest_name) shutil.move(entry.path, dest_name)
temp_path = r'{SYSTEMROOT}\Temp'.format(**global_vars['Env']) temp_path = r'{SYSTEMROOT}\Temp'.format(**global_vars['Env'])
for entry in os.scandir(temp_path): for entry in os.scandir(temp_path):
# cab_ files # cab_ files
if entry.name.lower().startswith('cab_'): if entry.name.lower().startswith('cab_'):
dest_name = r'{}\{}'.format(temp_folder, entry.name) dest_name = r'{}\{}'.format(temp_folder, entry.name)
dest_name = non_clobber_rename(dest_name) dest_name = non_clobber_rename(dest_name)
shutil.move(entry.path, 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(): def cleanup_desktop():
"""Move known backup files and reports into the ClientDir.""" """Move known backup files and reports into the ClientDir."""
dest_folder = r'{LogDir}\Tools'.format(**global_vars) dest_folder = r'{LogDir}\Tools'.format(**global_vars)
os.makedirs(dest_folder, exist_ok=True) os.makedirs(dest_folder, exist_ok=True)
desktop_path = r'{USERPROFILE}\Desktop'.format(**global_vars['Env']) desktop_path = r'{USERPROFILE}\Desktop'.format(**global_vars['Env'])
for entry in os.scandir(desktop_path): for entry in os.scandir(desktop_path):
# JRT, RKill, Shortcut cleaner if DESKTOP_ITEMS.search(entry.name):
if re.search(r'^(JRT|RKill|sc-cleaner)', entry.name, re.IGNORECASE): dest_name = r'{}\{}'.format(dest_folder, entry.name)
dest_name = r'{}\{}'.format(dest_folder, entry.name) dest_name = non_clobber_rename(dest_name)
dest_name = non_clobber_rename(dest_name) shutil.move(entry.path, 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): def delete_empty_folders(folder_path):
"""Delete all empty folders in path (depth first).""" """Delete all empty folders in path (depth first)."""
if not os.path.exists(folder_path) or not os.path.isdir(folder_path): if not os.path.exists(folder_path) or not os.path.isdir(folder_path):
# Bail early (silently) # Bail early (silently)
return return
# Delete empty subfolders first # Delete empty subfolders first
for item in os.scandir(folder_path): for item in os.scandir(folder_path):
if item.is_dir(): if item.is_dir():
delete_empty_folders(item.path) 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): def delete_registry_key(hive, key, recurse=False):
"""Delete a registry key and all it's subkeys.""" """Delete a registry key and all it's subkeys."""
access = winreg.KEY_ALL_ACCESS access = winreg.KEY_ALL_ACCESS
try: try:
if recurse: if recurse:
# Delete all subkeys first # Delete all subkeys first
with winreg.OpenKeyEx(hive, key, 0, access) as k: with winreg.OpenKeyEx(hive, key, 0, access) as k:
key_info = winreg.QueryInfoKey(k) key_info = winreg.QueryInfoKey(k)
for x in range(key_info[0]): for x in range(key_info[0]):
subkey = r'{}\{}'.format(key, winreg.EnumKey(k, 0)) subkey = r'{}\{}'.format(key, winreg.EnumKey(k, 0))
delete_registry_key(hive, subkey) 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): def delete_registry_value(hive, key, value):
"""Delete a registry value.""" """Delete a registry value."""
access = winreg.KEY_ALL_ACCESS access = winreg.KEY_ALL_ACCESS
with winreg.OpenKeyEx(hive, key, 0, access) as k: with winreg.OpenKeyEx(hive, key, 0, access) as k:
winreg.DeleteValue(k, value) 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__': 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=4 sw=4 ts=4

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 # Wizard Kit: Functions - Disk
from functions.common import * from functions.common import *
from functions import partition_uids from settings.partition_uids import *
# Regex # Regex
REGEX_BAD_PARTITION = re.compile(r'(RAW|Unknown)', re.IGNORECASE) REGEX_BAD_PARTITION = re.compile(r'(RAW|Unknown)', re.IGNORECASE)
REGEX_DISK_GPT = re.compile( REGEX_DISK_GPT = re.compile(
r'Disk ID: {[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+}', r'Disk ID: {[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+-[A-Z0-9]+}',
re.IGNORECASE) re.IGNORECASE)
REGEX_DISK_MBR = re.compile(r'Disk ID: [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) REGEX_DISK_RAW = re.compile(r'Disk ID: 00000000', re.IGNORECASE)
def assign_volume_letters(): def assign_volume_letters():
"""Assign a volume letter to all available volumes.""" """Assign a volume letter to all available volumes."""
remove_volume_letters() remove_volume_letters()
# Write script # Write script
script = [] script = []
for vol in get_volumes(): for vol in get_volumes():
script.append('select volume {}'.format(vol['Number'])) script.append('select volume {}'.format(vol['Number']))
script.append('assign') script.append('assign')
# Run
run_diskpart(script)
# Run
run_diskpart(script)
def get_boot_mode(): def get_boot_mode():
"""Check if the boot mode was UEFI or legacy.""" """Check if the boot mode was UEFI or legacy."""
boot_mode = 'Legacy' boot_mode = 'Legacy'
try: try:
reg_key = winreg.OpenKey( reg_key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE, r'System\CurrentControlSet\Control') winreg.HKEY_LOCAL_MACHINE, r'System\CurrentControlSet\Control')
reg_value = winreg.QueryValueEx(reg_key, 'PEFirmwareType')[0] reg_value = winreg.QueryValueEx(reg_key, 'PEFirmwareType')[0]
if reg_value == 2: if reg_value == 2:
boot_mode = 'UEFI' boot_mode = 'UEFI'
except: except:
boot_mode = 'Unknown' boot_mode = 'Unknown'
return boot_mode
return boot_mode
def get_disk_details(disk): def get_disk_details(disk):
"""Get disk details using DiskPart.""" """Get disk details using DiskPart."""
details = {} details = {}
script = [ script = [
'select disk {}'.format(disk['Number']), 'select disk {}'.format(disk['Number']),
'detail disk'] 'detail disk']
# Run # Run
try: try:
result = run_diskpart(script) result = run_diskpart(script)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
else: else:
output = result.stdout.decode().strip() output = result.stdout.decode().strip()
# Remove empty lines # Remove empty lines
tmp = [s.strip() for s in output.splitlines() if s.strip() != ''] tmp = [s.strip() for s in output.splitlines() if s.strip() != '']
# Set disk name # Set disk name
details['Name'] = tmp[4] details['Name'] = tmp[4]
# Split each line on ':' skipping those without ':' # Split each line on ':' skipping those without ':'
tmp = [s.split(':') for s in tmp if ':' in s] tmp = [s.split(':') for s in tmp if ':' in s]
# Add key/value pairs to the details variable and return dict # Add key/value pairs to the details variable and return dict
details.update({key.strip(): value.strip() for (key, value) in tmp}) details.update({key.strip(): value.strip() for (key, value) in tmp})
return details
return details
def get_disks(): def get_disks():
"""Get list of attached disks using DiskPart.""" """Get list of attached disks using DiskPart."""
disks = [] disks = []
try: try:
# Run script # Run script
result = run_diskpart(['list disk']) result = run_diskpart(['list disk'])
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
else: else:
# Append disk numbers # Append disk numbers
output = result.stdout.decode().strip() output = result.stdout.decode().strip()
for tmp in re.findall(r'Disk (\d+)\s+\w+\s+(\d+\s+\w+)', output): for tmp in re.findall(r'Disk (\d+)\s+\w+\s+(\d+\s+\w+)', output):
num = tmp[0] num = tmp[0]
size = human_readable_size(tmp[1]) size = human_readable_size(tmp[1])
disks.append({'Number': num, 'Size': size}) disks.append({'Number': num, 'Size': size})
return disks
return disks
def get_partition_details(disk, partition): def get_partition_details(disk, partition):
"""Get partition details using DiskPart and fsutil.""" """Get partition details using DiskPart and fsutil."""
details = {} details = {}
script = [ script = [
'select disk {}'.format(disk['Number']), 'select disk {}'.format(disk['Number']),
'select partition {}'.format(partition['Number']), 'select partition {}'.format(partition['Number']),
'detail partition'] '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: try:
# Run script tmp = psutil.disk_usage('{}:\\'.format(details['Letter']))
result = run_diskpart(script) except OSError as err:
except subprocess.CalledProcessError: details['FileSystem'] = 'Unknown'
pass details['Error'] = err.strerror
else: else:
# Get volume letter or RAW status details['Used Space'] = human_readable_size(tmp.used)
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 # fsutil details
guid = partition_uids.lookup_guid(details.get('Type')) cmd = [
if guid: 'fsutil',
details.update({ 'fsinfo',
'Description': guid.get('Description', '')[:29], 'volumeinfo',
'OS': guid.get('OS', 'Unknown')[:27]}) '{}:'.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: # Set Volume Name
# Disk usage details['Name'] = details.get('Volume Name', '')
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)
# fsutil details # Set FileSystem Type
cmd = [ if details.get('FileSystem', '') not in ['RAW', 'Unknown']:
'fsutil', details['FileSystem'] = details.get('File System Name', 'Unknown')
'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 Volume Name return details
details['Name'] = details.get('Volume Name', '')
# Set FileSystem Type
if details.get('FileSystem', '') not in ['RAW', 'Unknown']:
details['FileSystem'] = details.get('File System Name', 'Unknown')
return details
def get_partitions(disk): def get_partitions(disk):
"""Get list of partition using DiskPart.""" """Get list of partition using DiskPart."""
partitions = [] partitions = []
script = [ script = [
'select disk {}'.format(disk['Number']), 'select disk {}'.format(disk['Number']),
'list partition'] 'list partition']
try: try:
# Run script # Run script
result = run_diskpart(script) result = run_diskpart(script)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
else: else:
# Append partition numbers # Append partition numbers
output = result.stdout.decode().strip() output = result.stdout.decode().strip()
regex = r'Partition\s+(\d+)\s+\w+\s+(\d+\s+\w+)\s+' regex = r'Partition\s+(\d+)\s+\w+\s+(\d+\s+\w+)\s+'
for tmp in re.findall(regex, output, re.IGNORECASE): for tmp in re.findall(regex, output, re.IGNORECASE):
num = tmp[0] num = tmp[0]
size = human_readable_size(tmp[1]) size = human_readable_size(tmp[1])
partitions.append({'Number': num, 'Size': size}) partitions.append({'Number': num, 'Size': size})
return partitions
return partitions
def get_table_type(disk): def get_table_type(disk):
"""Get disk partition table type using DiskPart.""" """Get disk partition table type using DiskPart."""
part_type = 'Unknown' part_type = 'Unknown'
script = [ script = [
'select disk {}'.format(disk['Number']), 'select disk {}'.format(disk['Number']),
'uniqueid disk'] 'uniqueid disk']
try: try:
result = run_diskpart(script) result = run_diskpart(script)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
else: else:
output = result.stdout.decode().strip() output = result.stdout.decode().strip()
if REGEX_DISK_GPT.search(output): if REGEX_DISK_GPT.search(output):
part_type = 'GPT' part_type = 'GPT'
elif REGEX_DISK_MBR.search(output): elif REGEX_DISK_MBR.search(output):
part_type = 'MBR' part_type = 'MBR'
elif REGEX_DISK_RAW.search(output): elif REGEX_DISK_RAW.search(output):
part_type = 'RAW' part_type = 'RAW'
return part_type
return part_type
def get_volumes(): def get_volumes():
"""Get list of volumes using DiskPart.""" """Get list of volumes using DiskPart."""
vols = [] vols = []
try: try:
result = run_diskpart(['list volume']) result = run_diskpart(['list volume'])
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
else: else:
# Append volume numbers # Append volume numbers
output = result.stdout.decode().strip() output = result.stdout.decode().strip()
for tmp in re.findall(r'Volume (\d+)\s+([A-Za-z]?)\s+', output): for tmp in re.findall(r'Volume (\d+)\s+([A-Za-z]?)\s+', output):
vols.append({'Number': tmp[0], 'Letter': tmp[1]}) vols.append({'Number': tmp[0], 'Letter': tmp[1]})
return vols
return vols
def is_bad_partition(par): def is_bad_partition(par):
"""Check if the partition is accessible.""" """Check if the partition is accessible."""
return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem']) return 'Letter' not in par or REGEX_BAD_PARTITION.search(par['FileSystem'])
def prep_disk_for_formatting(disk=None): def prep_disk_for_formatting(disk=None):
"""Gather details about the disk and its partitions.""" """Gather details about the disk and its partitions."""
disk['Format Warnings'] = '\n' disk['Format Warnings'] = '\n'
width = len(str(len(disk['Partitions']))) width = len(str(len(disk['Partitions'])))
# Bail early # Bail early
if disk is None: if disk is None:
raise Exception('Disk not provided.') raise Exception('Disk not provided.')
# Set boot method and partition table type # Set boot method and partition table type
disk['Use GPT'] = True disk['Use GPT'] = True
if (get_boot_mode() == 'UEFI'): if (get_boot_mode() == 'UEFI'):
if (not ask("Setup Windows to use UEFI booting?")): if (not ask("Setup Windows to use UEFI booting?")):
disk['Use GPT'] = False 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: else:
if (ask("Setup Windows to use BIOS/Legacy booting?")): # List space used instead of partition description & OS type
disk['Use GPT'] = False 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'): def reassign_volume_letter(letter, new_letter='I'):
"""Assign a new letter to a volume using DiskPart.""" """Assign a new letter to a volume using DiskPart."""
if not letter: if not letter:
# Ignore # Ignore
return None return None
script = [ script = [
'select volume {}'.format(letter), 'select volume {}'.format(letter),
'remove noerr', 'remove noerr',
'assign letter={}'.format(new_letter)] 'assign letter={}'.format(new_letter)]
try: try:
run_diskpart(script) run_diskpart(script)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
pass pass
else: else:
return new_letter return new_letter
def remove_volume_letters(keep=None): def remove_volume_letters(keep=None):
"""Remove all assigned volume letters using DiskPart.""" """Remove all assigned volume letters using DiskPart."""
if not keep: if not keep:
keep = '' keep = ''
script = [] script = []
for vol in get_volumes(): for vol in get_volumes():
if vol['Letter'].upper() != keep.upper(): if vol['Letter'].upper() != keep.upper():
script.append('select volume {}'.format(vol['Number'])) script.append('select volume {}'.format(vol['Number']))
script.append('remove noerr') 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): def run_diskpart(script):
"""Run DiskPart script.""" """Run DiskPart script."""
tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP']) tempfile = r'{}\diskpart.script'.format(global_vars['Env']['TMP'])
# Write script # Write script
with open(tempfile, 'w') as f: with open(tempfile, 'w') as f:
for line in script: for line in script:
f.write('{}\n'.format(line)) 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(): def scan_disks():
"""Get details about the attached disks""" """Get details about the attached disks"""
disks = get_disks() disks = get_disks()
# Get disk details # Get disk details
for disk in disks: for disk in disks:
# Get partition style # Get partition style
disk['Table'] = get_table_type(disk) disk['Table'] = get_table_type(disk)
# Get disk name/model and physical details # Get disk name/model and physical details
disk.update(get_disk_details(disk)) disk.update(get_disk_details(disk))
# Get partition info for disk # Get partition info for disk
disk['Partitions'] = get_partitions(disk) disk['Partitions'] = get_partitions(disk)
for partition in disk['Partitions']: for partition in disk['Partitions']:
# Get partition details # Get partition details
partition.update(get_partition_details(disk, partition)) partition.update(get_partition_details(disk, partition))
# Done
return disks
# Done
return disks
def select_disk(title='Which disk?', disks=[]): def select_disk(title='Which disk?', disks=[]):
"""Select a disk from the attached disks""" """Select a disk from the attached disks"""
# Build menu # Build menu
disk_options = [] disk_options = []
for disk in disks: for disk in disks:
display_name = '{}\t[{}] ({}) {}'.format( display_name = '{}\t[{}] ({}) {}'.format(
disk.get('Size', ''), disk.get('Size', ''),
disk.get('Table', ''), disk.get('Table', ''),
disk.get('Type', ''), disk.get('Type', ''),
disk.get('Name', 'Unknown'), disk.get('Name', 'Unknown'),
) )
pwidth=len(str(len(disk['Partitions']))) pwidth=len(str(len(disk['Partitions'])))
for partition in disk['Partitions']: for partition in disk['Partitions']:
# Main text # Main text
p_name = 'Partition {num:>{width}}: {size} ({fs})'.format( p_name = 'Partition {num:>{width}}: {size} ({fs})'.format(
num = partition['Number'], num = partition['Number'],
width = pwidth, width = pwidth,
size = partition['Size'], size = partition['Size'],
fs = partition['FileSystem']) fs = partition['FileSystem'])
if partition['Name']: if partition['Name']:
p_name += '\t"{}"'.format(partition['Name']) p_name += '\t"{}"'.format(partition['Name'])
# Show unsupported partition(s) # Show unsupported partition(s)
if is_bad_partition(partition): if is_bad_partition(partition):
p_name = '{YELLOW}{p_name}{CLEAR}'.format( p_name = '{YELLOW}{p_name}{CLEAR}'.format(
p_name=p_name, **COLORS) p_name=p_name, **COLORS)
display_name += '\n\t\t\t{}'.format(p_name) display_name += '\n\t\t\t{}'.format(p_name)
if not disk['Partitions']: if not disk['Partitions']:
display_name += '\n\t\t\t{}No partitions found.{}'.format( display_name += '\n\t\t\t{}No partitions found.{}'.format(
COLORS['YELLOW'], COLORS['CLEAR']) COLORS['YELLOW'], COLORS['CLEAR'])
disk_options.append({'Name': display_name, 'Disk': disk}) disk_options.append({'Name': display_name, 'Disk': disk})
actions = [ actions = [
{'Name': 'Main Menu', 'Letter': 'M'}, {'Name': 'Main Menu', 'Letter': 'M'},
] ]
# Menu loop # Menu loop
selection = menu_select( selection = menu_select(
title = title, title = title,
main_entries = disk_options, main_entries = disk_options,
action_entries = actions) 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__': 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 # Wizard Kit: Functions - Information
from borrowed import knownpaths from borrowed import knownpaths
from operator import itemgetter
from functions.common import *
from functions.activation 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(): def backup_file_list():
"""Export current file listing for the system.""" """Export current file listing for the system."""
extract_item('Everything', silent=True) extract_item('Everything', silent=True)
cmd = [ cmd = [
global_vars['Tools']['Everything'], global_vars['Tools']['Everything'],
'-nodb', '-nodb',
'-create-filelist', '-create-filelist',
r'{LogDir}\File List.txt'.format(**global_vars), r'{LogDir}\File List.txt'.format(**global_vars),
global_vars['Env']['SYSTEMDRIVE']] global_vars['Env']['SYSTEMDRIVE']]
run_program(cmd) run_program(cmd)
def backup_power_plans(): def backup_power_plans():
"""Export current power plans.""" """Export current power plans."""
os.makedirs(r'{BackupDir}\Power Plans\{Date}'.format( os.makedirs(r'{BackupDir}\Power Plans\{Date}'.format(
**global_vars), exist_ok=True) **global_vars), exist_ok=True)
plans = run_program(['powercfg', '/L']) plans = run_program(['powercfg', '/L'])
plans = plans.stdout.decode().splitlines() plans = plans.stdout.decode().splitlines()
plans = [p for p in plans if re.search(r'^Power Scheme', p)] plans = [p for p in plans if re.search(r'^Power Scheme', p)]
for p in plans: for p in plans:
guid = re.sub(r'Power Scheme GUID:\s+([0-9a-f\-]+).*', r'\1', p) guid = re.sub(r'Power Scheme GUID:\s+([0-9a-f\-]+).*', r'\1', p)
name = re.sub( name = re.sub(
r'Power Scheme GUID:\s+[0-9a-f\-]+\s+\(([^\)]+)\).*', r'\1', p) r'Power Scheme GUID:\s+[0-9a-f\-]+\s+\(([^\)]+)\).*', r'\1', p)
out = r'{BackupDir}\Power Plans\{Date}\{name}.pow'.format( out = r'{BackupDir}\Power Plans\{Date}\{name}.pow'.format(
name=name, **global_vars) name=name, **global_vars)
if not os.path.exists(out): if not os.path.exists(out):
cmd = ['powercfg', '-export', out, guid] cmd = ['powercfg', '-export', out, guid]
run_program(cmd, check=False) run_program(cmd, check=False)
def backup_registry(overwrite=False): def backup_registry(overwrite=False):
"""Backup registry including user hives.""" """Backup registry including user hives."""
extract_item('erunt', silent=True) extract_item('erunt', silent=True)
cmd = [ cmd = [
global_vars['Tools']['ERUNT'], global_vars['Tools']['ERUNT'],
r'{BackupDir}\Registry\{Date}'.format(**global_vars), r'{BackupDir}\Registry\{Date}'.format(**global_vars),
'sysreg', 'sysreg',
'curuser', 'curuser',
'otherusers', 'otherusers',
'/noprogresswindow'] '/noprogresswindow']
if overwrite: if overwrite:
cmd.append('/noconfirmdelete') cmd.append('/noconfirmdelete')
run_program(cmd) run_program(cmd)
def get_folder_size(path): def get_folder_size(path):
"""Get (human-readable) size of folder passed, returns str.""" """Get (human-readable) size of folder passed, returns str."""
size = 'Unknown' size = 'Unknown'
cmd = [global_vars['Tools']['Du'], '-c', '-nobanner', '-q', path] 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: try:
out = run_program(cmd) size = out.stdout.decode().split(',')[-2]
except FileNotFoundError: except IndexError:
# Failed to find folder # Failed to parse csv data
pass pass
except subprocess.CalledProcessError:
# Failed to get folder size
pass
else: else:
try: size = human_readable_size(size)
size = out.stdout.decode().split(',')[-2] return size
except IndexError:
# Failed to parse csv data
pass
else:
size = human_readable_size(size)
return size
def get_installed_antivirus(): def get_installed_antivirus():
"""Get list of installed Antivirus programs.""" """Get list of installed Antivirus programs."""
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', cmd = ['WMIC', r'/namespace:\\root\SecurityCenter2',
'path', 'AntivirusProduct', 'path', 'AntivirusProduct',
'get', 'displayName', '/value'] 'where', 'displayName="{}"'.format(prod),
'get', 'productState', '/value']
out = run_program(cmd) out = run_program(cmd)
out = out.stdout.decode().strip() out = out.stdout.decode().strip()
products = out.splitlines() state = out.split('=')[1]
products = [p.split('=')[1] for p in products if p] state = hex(int(state))
for prod in sorted(products): if str(state)[3:5] not in ['10', '11']:
# Get product state and check if it's enabled programs.append('[Disabled] {}'.format(prod))
# credit: https://jdhitsolutions.com/blog/powershell/5187/get-antivirus-product-status-with-powershell/ else:
cmd = ['WMIC', r'/namespace:\\root\SecurityCenter2', programs.append(prod)
'path', 'AntivirusProduct',
'where', 'displayName="{}"'.format(prod), if len(programs) == 0:
'get', 'productState', '/value'] programs = ['No programs found']
out = run_program(cmd) return programs
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)
if len(programs) == 0:
programs = ['No programs found']
return programs
def get_installed_office(): def get_installed_office():
"""Get list of installed Office programs.""" """Get list of installed Office programs."""
programs = [] programs = []
log_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format( log_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format(
**global_vars) **global_vars)
with open (log_file, 'r') as f: with open (log_file, 'r') as f:
for line in sorted(f.readlines()): for line in sorted(f.readlines()):
if REGEX_OFFICE.search(line): if REGEX_OFFICE.search(line):
programs.append(line[4:82].strip()) 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'): 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. NOTE: Only works for the current user.
Code based on https://gist.github.com/mkropat/7550097 Code based on https://gist.github.com/mkropat/7550097
""" """
path = None path = None
folderid = None folderid = None
if user.lower() == 'public': if user.lower() == 'public':
user = 'common' user = 'common'
try:
folderid = getattr(knownpaths.FOLDERID, folder)
except AttributeError:
# Unknown folder ID, ignore and return None
pass
if folderid:
try: try:
folderid = getattr(knownpaths.FOLDERID, folder) path = knownpaths.get_path(
except AttributeError: folderid, getattr(knownpaths.UserHandle, user))
# Unknown folder ID, ignore and return None except PathNotFoundError:
pass # Folder not found, ignore and return None
pass
if folderid: return path
try:
path = knownpaths.get_path(folderid, getattr(knownpaths.UserHandle, user))
except PathNotFoundError:
# Folder not found, ignore and return None
pass
return path
def get_user_data_paths(user): def get_user_data_paths(user):
"""Get user data paths for provided user, returns dict.""" """Get user data paths for provided user, returns dict."""
hive_path = user['SID'] hive_path = user['SID']
paths = { paths = {
'Profile': { 'Profile': {
'Path': None, 'Path': None,
}, },
'Shell Folders': {}, 'Shell Folders': {},
'Extra Folders': {}, 'Extra Folders': {},
} }
unload_hive = False unload_hive = False
if user['Name'] == global_vars['Env']['USERNAME']: if user['Name'] == global_vars['Env']['USERNAME']:
# We can use SHGetKnownFolderPath for the current user # We can use SHGetKnownFolderPath for the current user
paths['Profile']['Path'] = get_shell_path('Profile') paths['Profile']['Path'] = get_shell_path('Profile')
paths['Shell Folders'] = {f: {'Path': get_shell_path(f)} paths['Shell Folders'] = {f: {'Path': get_shell_path(f)}
for f in SHELL_FOLDERS.keys()} for f in SHELL_FOLDERS.keys()}
else: else:
# We have to use the NTUSER.dat hives which isn't recommended by MS # We have to use the NTUSER.dat hives which isn't recommended by MS
try: try:
key_path = r'{}\{}'.format(REG_PROFILE_LIST, user['SID']) key_path = r'{}\{}'.format(REG_PROFILE_LIST, user['SID'])
with winreg.OpenKey(HKLM, key_path) as key: with winreg.OpenKey(HKLM, key_path) as key:
paths['Profile']['Path'] = winreg.QueryValueEx( paths['Profile']['Path'] = winreg.QueryValueEx(
key, 'ProfileImagePath')[0] key, 'ProfileImagePath')[0]
except Exception: except Exception:
# Profile path not found, leaving as None. # Profile path not found, leaving as None.
pass pass
# Shell folders (Prep) # Shell folders (Prep)
if not reg_path_exists(HKU, hive_path) and paths['Profile']['Path']: if not reg_path_exists(HKU, hive_path) and paths['Profile']['Path']:
# User not logged-in, loading hive # User not logged-in, loading hive
# Also setting unload_hive so it will be unloaded later. # Also setting unload_hive so it will be unloaded later.
hive_path = TMP_HIVE_PATH hive_path = TMP_HIVE_PATH
cmd = ['reg', 'load', r'HKU\{}'.format(TMP_HIVE_PATH), cmd = ['reg', 'load', r'HKU\{}'.format(TMP_HIVE_PATH),
r'{}\NTUSER.DAT'.format(paths['Profile']['Path'])] r'{}\NTUSER.DAT'.format(paths['Profile']['Path'])]
unload_hive = True 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: try:
run_program(cmd) path = winreg.QueryValueEx(key, value)[0]
except subprocess.CalledProcessError: except FileNotFoundError:
# Failed to load user hive # Skip missing values
pass pass
else:
paths['Shell Folders'][folder] = {'Path': path}
# Stop checking values for this folder
break
# Shell folders # Shell folder (extra check)
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
if paths['Profile']['Path']: if paths['Profile']['Path']:
for folder in EXTRA_FOLDERS: for folder in SHELL_FOLDERS.keys():
folder_path = r'{Path}\{folder}'.format( folder_path = r'{Path}\{folder}'.format(
folder=folder, **paths['Profile']) folder=folder, **paths['Profile'])
if os.path.exists(folder_path): if (folder not in paths['Shell Folders']
paths['Extra Folders'][folder] = {'Path': folder_path} and os.path.exists(folder_path)):
paths['Shell Folders'][folder] = {'Path': folder_path}
# Shell folders (cleanup) # Extra folders
if unload_hive: if paths['Profile']['Path']:
cmd = ['reg', 'unload', r'HKU\{}'.format(TMP_HIVE_PATH)] for folder in EXTRA_FOLDERS:
run_program(cmd, check=False) 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): def get_user_folder_sizes(users):
"""Update list(users) to include folder paths and sizes.""" """Update list(users) to include folder paths and sizes."""
extract_item('du', filter='du*', silent=True) extract_item('du', filter='du*', silent=True)
# Configure Du # Configure Du
winreg.CreateKey(HKCU, r'Software\Sysinternals\Du') winreg.CreateKey(HKCU, r'Software\Sysinternals\Du')
with winreg.OpenKey(HKCU, with winreg.OpenKey(HKCU,
r'Software\Sysinternals\Du', access=winreg.KEY_WRITE) as key: r'Software\Sysinternals\Du', access=winreg.KEY_WRITE) as key:
winreg.SetValueEx(key, 'EulaAccepted', 0, winreg.REG_DWORD, 1) 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(): def get_user_list():
"""Get user list via WMIC, returns list of dicts.""" """Get user list via WMIC, returns list of dicts."""
users = [] users = []
# Get user info from WMI # Get user info from WMI
cmd = ['wmic', 'useraccount', 'get', '/format:csv'] cmd = ['wmic', 'useraccount', 'get', '/format:csv']
try: try:
out = run_program(cmd) out = run_program(cmd)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
# Meh, return empty list to avoid a full crash # 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 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): def reg_path_exists(hive, path):
"""Test if specified path exists, returns bool.""" """Test if specified path exists, returns bool."""
try: try:
winreg.QueryValue(hive, path) winreg.QueryValue(hive, path)
except FileNotFoundError: except FileNotFoundError:
return False return False
else: else:
return True return True
def run_aida64(): def run_aida64():
"""Run AIDA64 to save system reports.""" """Run AIDA64 to save system reports."""
extract_item('AIDA64', silent=True) extract_item('AIDA64', silent=True)
# All system info # All system info
config = r'{BinDir}\AIDA64\full.rpf'.format(**global_vars) config = r'{BinDir}\AIDA64\full.rpf'.format(**global_vars)
report_file = r'{LogDir}\System Information (AIDA64).html'.format( report_file = r'{LogDir}\System Information (AIDA64).html'.format(
**global_vars) **global_vars)
if not os.path.exists(report_file): if not os.path.exists(report_file):
cmd = [ cmd = [
global_vars['Tools']['AIDA64'], global_vars['Tools']['AIDA64'],
'/R', report_file, '/R', report_file,
'/CUSTOM', config, '/CUSTOM', config,
'/HTML', '/SILENT', '/SAFEST'] '/HTML', '/SILENT', '/SAFEST']
run_program(cmd, check=False) run_program(cmd, check=False)
# Installed Programs # Installed Programs
config = r'{BinDir}\AIDA64\installed_programs.rpf'.format(**global_vars) config = r'{BinDir}\AIDA64\installed_programs.rpf'.format(**global_vars)
report_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format( report_file = r'{LogDir}\Installed Program List (AIDA64).txt'.format(
**global_vars) **global_vars)
if not os.path.exists(report_file): if not os.path.exists(report_file):
cmd = [ cmd = [
global_vars['Tools']['AIDA64'], global_vars['Tools']['AIDA64'],
'/R', report_file, '/R', report_file,
'/CUSTOM', config, '/CUSTOM', config,
'/TEXT', '/SILENT', '/SAFEST'] '/TEXT', '/SILENT', '/SAFEST']
run_program(cmd, check=False) 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): 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.""" If preview is True then no files should be deleted."""
error_path = r'{}\Tools\BleachBit.err'.format(global_vars['LogDir']) error_path = r'{}\Tools\BleachBit.err'.format(global_vars['LogDir'])
log_path = error_path.replace('err', 'log') log_path = error_path.replace('err', 'log')
extract_item('BleachBit', silent=True) extract_item('BleachBit', silent=True)
# Safety check # Safety check
if not cleaners: if not cleaners:
# Disable cleaning and use preset config # Disable cleaning and use preset config
cleaners = ['--preset'] cleaners = ['--preset']
preview = True preview = True
# Run # Run
cmd = [ cmd = [
global_vars['Tools']['BleachBit'], global_vars['Tools']['BleachBit'],
'--preview' if preview else '--clean'] '--preview' if preview else '--clean']
cmd.extend(cleaners) cmd.extend(cleaners)
out = run_program(cmd, check=False) out = run_program(cmd, check=False)
# Save stderr # Save stderr
if out.stderr.decode().splitlines(): if out.stderr.decode().splitlines():
with open(error_path, 'a', encoding='utf-8') as f: with open(error_path, 'a', encoding='utf-8') as f:
for line in out.stderr.decode().splitlines(): for line in out.stderr.decode().splitlines():
f.write(line.strip() + '\n') 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): def show_disk_usage(disk):
"""Show free and used space for a specified disk.""" """Show free and used space for a specified disk."""
print_standard('{:5}'.format(disk.device.replace('/', ' ')), print_standard('{:5}'.format(disk.device.replace('/', ' ')),
end='', flush=True, timestamp=False) end='', flush=True, timestamp=False)
try: try:
usage = psutil.disk_usage(disk.device) usage = psutil.disk_usage(disk.device)
display_string = '{percent:>5.2f}% Free ({free} / {total})'.format( display_string = '{percent:>5.2f}% Free ({free} / {total})'.format(
percent = 100 - usage.percent, percent = 100 - usage.percent,
free = human_readable_size(usage.free, 2), free = human_readable_size(usage.free, 2),
total = human_readable_size(usage.total, 2)) total = human_readable_size(usage.total, 2))
if usage.percent > 85: if usage.percent > 85:
print_error(display_string, timestamp=False) print_error(display_string, timestamp=False)
elif usage.percent > 75: elif usage.percent > 75:
print_warning(display_string, timestamp=False) print_warning(display_string, timestamp=False)
else: else:
print_standard(display_string, timestamp=False) print_standard(display_string, timestamp=False)
except Exception: except Exception:
print_warning('Unknown', timestamp=False) print_warning('Unknown', timestamp=False)
def show_free_space(indent=8, width=32): def show_free_space(indent=8, width=32):
"""Show free space info for all fixed disks.""" """Show free space info for all fixed disks."""
message = 'Free Space:' message = 'Free Space:'
for disk in psutil.disk_partitions(): for disk in psutil.disk_partitions():
try: try:
if 'fixed' in disk.opts: if 'fixed' in disk.opts:
try_and_print(message=message, function=show_disk_usage, try_and_print(message=message, function=show_disk_usage,
ns='Unknown', silent_function=False, ns='Unknown', silent_function=False,
indent=indent, width=width, disk=disk) indent=indent, width=width, disk=disk)
message = '' message = ''
except Exception: except Exception:
pass pass
def show_installed_ram(): def show_installed_ram():
"""Show installed RAM.""" """Show installed RAM."""
mem = psutil.virtual_memory() mem = psutil.virtual_memory()
if mem.total > 5905580032: if mem.total > 5905580032:
# > 5.5 Gb so 6Gb or greater # > 5.5 Gb so 6Gb or greater
print_standard(human_readable_size(mem.total).strip(), timestamp=False) print_standard(human_readable_size(mem.total).strip(), timestamp=False)
elif mem.total > 3758096384: elif mem.total > 3758096384:
# > 3.5 Gb so 4Gb or greater # > 3.5 Gb so 4Gb or greater
print_warning(human_readable_size(mem.total).strip(), timestamp=False) print_warning(human_readable_size(mem.total).strip(), timestamp=False)
else: else:
print_error(human_readable_size(mem.total).strip(), timestamp=False) print_error(human_readable_size(mem.total).strip(), timestamp=False)
def show_os_activation(): def show_os_activation():
"""Show OS activation info.""" """Show OS activation info."""
act_str = get_activation_string() act_str = get_activation_string()
if windows_is_activated(): if windows_is_activated():
print_standard(act_str, timestamp=False) print_standard(act_str, timestamp=False)
elif re.search(r'unavailable', act_str, re.IGNORECASE): elif re.search(r'unavailable', act_str, re.IGNORECASE):
print_warning(act_str, timestamp=False) print_warning(act_str, timestamp=False)
else: else:
print_error(act_str, timestamp=False) print_error(act_str, timestamp=False)
def show_os_name(): def show_os_name():
"""Show extended OS name (including warnings).""" """Show extended OS name (including warnings)."""
os_name = global_vars['OS']['DisplayName'] os_name = global_vars['OS']['DisplayName']
if global_vars['OS']['Arch'] == 32: if global_vars['OS']['Arch'] == 32:
# Show all 32-bit installs as an error message # Show all 32-bit installs as an error message
print_error(os_name, timestamp=False) 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: else:
if re.search(r'(preview build|unrecognized|unsupported)', os_name, re.IGNORECASE): print_standard(os_name, timestamp=False)
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)
def show_temp_files_size(): def show_temp_files_size():
"""Show total size of temp files identified by BleachBit.""" """Show total size of temp files identified by BleachBit."""
size = None size_str = None
with open(r'{LogDir}\Tools\BleachBit.log'.format(**global_vars), 'r') as f: total = 0
for line in f.readlines(): with open(r'{LogDir}\Tools\BleachBit.log'.format(**global_vars), 'r') as f:
if re.search(r'^disk space to be recovered:', line, re.IGNORECASE): for line in f.readlines():
size = re.sub(r'.*: ', '', line.strip()) if re.search(r'^Disk space (to be |)recovered:', line, re.IGNORECASE):
size = re.sub(r'(\w)iB$', r' \1b', size) size = re.sub(r'.*: ', '', line.strip())
if size is None: size = re.sub(r'(\w)iB$', r' \1b', size)
print_warning(size, timestamp=False) total += convert_to_bytes(size)
else: size_str = human_readable_size(total, decimals=1)
print_standard(size, timestamp=False) 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): def show_user_data_summary(indent=8, width=32):
"""Print user data folder sizes for all users.""" """Print user data folder sizes for all users."""
users = get_user_list() users = get_user_list()
users = [u for u in users if u['Active']] users = [u for u in users if u['Active']]
get_user_folder_sizes(users) get_user_folder_sizes(users)
for user in users: for user in users:
if ('Size' not in user['Profile'] if ('Size' not in user['Profile']
and not any(user['Shell Folders']) and not any(user['Shell Folders'])
and not any(user['Extra Folders'])): and not any(user['Extra Folders'])):
# Skip empty users # Skip empty users
continue continue
print_success('{indent}User: {user}'.format( print_success('{indent}User: {user}'.format(
indent = ' '*int(indent/2), indent = ' '*int(indent/2),
user = user['Name'])) user = user['Name']))
for section in ['Profile', None, 'Shell Folders', 'Extra Folders']: for section in ['Profile', None, 'Shell Folders', 'Extra Folders']:
folders = [] folders = []
if section is None: if section is None:
# Divider # Divider
print_standard('{}{}'.format(' '*indent, '-'*(width+6))) print_standard('{}{}'.format(' '*indent, '-'*(width+6)))
elif section == 'Profile': elif section == 'Profile':
folders = {'Profile': user['Profile']} folders = {'Profile': user['Profile']}
else: else:
folders = user[section] folders = user[section]
for folder in folders: for folder in folders:
print_standard( print_standard(
'{indent}{folder:<{width}}{size:>6} ({path})'.format( '{indent}{folder:<{width}}{size:>6} ({path})'.format(
indent = ' ' * indent, indent = ' ' * indent,
width = width, width = width,
folder = folder, folder = folder,
size = folders[folder].get('Size', 'Unknown'), size = folders[folder].get('Size', 'Unknown'),
path = folders[folder].get('Path', 'Unknown'))) path = folders[folder].get('Path', 'Unknown')))
if __name__ == '__main__': 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 os
import shutil import shutil
import sys import sys
# Init
os.chdir(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.common import * from functions.common import *
# REGEX # REGEX
REGEX_VALID_IP = re.compile( REGEX_VALID_IP = re.compile(
r'(10.\d+.\d+.\d+' r'(10.\d+.\d+.\d+'
r'|172.(1[6-9]|2\d|3[0-1])' r'|172.(1[6-9]|2\d|3[0-1])'
r'|192.168.\d+.\d+)', r'|192.168.\d+.\d+)',
re.IGNORECASE) 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(): def is_connected():
"""Check for a valid private IP.""" """Check for a valid private IP."""
devs = psutil.net_if_addrs() devs = psutil.net_if_addrs()
for dev in devs.values(): for dev in devs.values():
for family in dev: for family in dev:
if REGEX_VALID_IP.search(family.address): if REGEX_VALID_IP.search(family.address):
# Valid IP found # Valid IP found
return True return True
# Else # Else
return False return False
def show_valid_addresses(): def show_valid_addresses():
"""Show all valid private IP addresses assigned to the system.""" """Show all valid private IP addresses assigned to the system."""
devs = psutil.net_if_addrs() devs = psutil.net_if_addrs()
for dev, families in sorted(devs.items()): for dev, families in sorted(devs.items()):
for family in families: for family in families:
if REGEX_VALID_IP.search(family.address): if REGEX_VALID_IP.search(family.address):
# Valid IP found # Valid IP found
show_data(message=dev, data=family.address) show_data(message=dev, data=family.address)
def speedtest(): def speedtest():
"""Run a network speedtest using speedtest-cli.""" """Run a network speedtest using speedtest-cli."""
result = run_program(['speedtest-cli', '--simple']) result = run_program(['speedtest-cli', '--simple'])
output = [line.strip() for line in result.stdout.decode().splitlines() output = [line.strip() for line in result.stdout.decode().splitlines()
if line.strip()] if line.strip()]
output = [line.split() for line in output] output = [line.split() for line in output]
output = [(a, float(b), c) for a, b, c in output] output = [(a, float(b), c) for a, b, c in output]
return ['{:10}{:6.2f} {}'.format(*line) for line in output] return ['{:10}{:6.2f} {}'.format(*line) for line in output]
if __name__ == '__main__': 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 * from functions.common import *
# Regex # Regex
REGEX_REGISTRY_DIRS = re.compile( REGEX_REGISTRY_DIRS = re.compile(
r'^(config$|RegBack$|System32$|Transfer|Win)', r'^(config$|RegBack$|System32$|Transfer|Win)',
re.IGNORECASE) re.IGNORECASE)
REGEX_SOFTWARE_HIVE = re.compile(r'^Software$', re.IGNORECASE) REGEX_SOFTWARE_HIVE = re.compile(r'^Software$', re.IGNORECASE)
def extract_keys(): def extract_keys():
"""Extract keys from provided hives and return a dict.""" """Extract keys from provided hives and return a dict."""
keys = {} keys = {}
# Extract keys # Extract keys
extract_item('ProduKey', silent=True) extract_item('ProduKey', silent=True)
for hive in find_software_hives(): for hive in find_software_hives():
cmd = [ cmd = [
global_vars['Tools']['ProduKey'], global_vars['Tools']['ProduKey'],
'/IEKeys', '0', '/IEKeys', '0',
'/WindowsKeys', '1', '/WindowsKeys', '1',
'/OfficeKeys', '1', '/OfficeKeys', '1',
'/ExtractEdition', '1', '/ExtractEdition', '1',
'/nosavereg', '/nosavereg',
'/regfile', hive, '/regfile', hive,
'/scomma', ''] '/scomma', '']
try: try:
out = run_program(cmd) out = run_program(cmd)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
# Ignore and return empty dict # Ignore and return empty dict
pass pass
else: else:
for line in out.stdout.decode().splitlines(): for line in out.stdout.decode().splitlines():
# Add key to keys under product only if unique # Add key to keys under product only if unique
tmp = line.split(',') tmp = line.split(',')
product = tmp[0] product = tmp[0]
key = tmp[2] key = tmp[2]
if product not in keys: if product not in keys:
keys[product] = [] keys[product] = []
if key not in keys[product]: if key not in keys[product]:
keys[product].append(key) keys[product].append(key)
# Done
return keys
# Done
return keys
def list_clientdir_keys(): def list_clientdir_keys():
"""List product keys found in hives inside the ClientDir.""" """List product keys found in hives inside the ClientDir."""
keys = extract_keys() keys = extract_keys()
key_list = [] key_list = []
if keys: if keys:
for product in sorted(keys): for product in sorted(keys):
key_list.append(product) key_list.append(product)
for key in sorted(keys[product]): for key in sorted(keys[product]):
key_list.append(' {key}'.format(key=key)) key_list.append(' {key}'.format(key=key))
else: else:
key_list.append('No keys found.') key_list.append('No keys found.')
return key_list
return key_list
def find_software_hives(): def find_software_hives():
"""Search for transferred SW hives and return a list.""" """Search for transferred SW hives and return a list."""
hives = [] hives = []
search_paths = [global_vars['ClientDir']] search_paths = [global_vars['ClientDir']]
while len(search_paths) > 0: while len(search_paths) > 0:
for item in os.scandir(search_paths.pop(0)): for item in os.scandir(search_paths.pop(0)):
if item.is_dir() and REGEX_REGISTRY_DIRS.search(item.name): if item.is_dir() and REGEX_REGISTRY_DIRS.search(item.name):
search_paths.append(item.path) search_paths.append(item.path)
if item.is_file() and REGEX_SOFTWARE_HIVE.search(item.name): if item.is_file() and REGEX_SOFTWARE_HIVE.search(item.name):
hives.append(item.path) hives.append(item.path)
return hives
return hives
def get_product_keys(): def get_product_keys():
"""List product keys from saved report.""" """List product keys from saved report."""
keys = [] keys = []
log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars) log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars)
with open (log_file, 'r') as f: with open (log_file, 'r') as f:
for line in f.readlines(): for line in f.readlines():
if re.search(r'^Product Name', line): if re.search(r'^Product Name', line):
line = re.sub(r'^Product Name\s+:\s+(.*)', r'\1', line.strip()) line = re.sub(r'^Product Name\s+:\s+(.*)', r'\1', line.strip())
keys.append(line) 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(): def run_produkey():
"""Run ProduKey and save report in the ClientDir.""" """Run ProduKey and save report in the ClientDir."""
extract_item('ProduKey', silent=True) extract_item('ProduKey', silent=True)
log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars) log_file = r'{LogDir}\Product Keys (ProduKey).txt'.format(**global_vars)
if not os.path.exists(log_file): if not os.path.exists(log_file):
# Clear current configuration # Clear current configuration
for config in ['ProduKey.cfg', 'ProduKey64.cfg']: for config in ['ProduKey.cfg', 'ProduKey64.cfg']:
config = r'{BinDir}\ProduKey\{config}'.format( config = r'{BinDir}\ProduKey\{config}'.format(
config=config, **global_vars) config=config, **global_vars)
try: try:
if os.path.exists(config): if os.path.exists(config):
os.remove(config) os.remove(config)
except Exception: except Exception:
pass pass
cmd = [ cmd = [
global_vars['Tools']['ProduKey'], global_vars['Tools']['ProduKey'],
'/nosavereg', '/nosavereg',
'/stext', '/stext',
log_file] log_file]
run_program(cmd, check=False) run_program(cmd, check=False)
if __name__ == '__main__': 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 * from functions.common import *
def run_chkdsk(repair=False): def run_chkdsk(repair=False):
"""Run CHKDSK scan or schedule offline repairs.""" """Run CHKDSK scan or schedule offline repairs."""
if repair: if repair:
run_chkdsk_offline() run_chkdsk_offline()
else: else:
run_chkdsk_scan() run_chkdsk_scan()
def run_chkdsk_scan(): def run_chkdsk_scan():
"""Run CHKDSK in a "split window" and report errors.""" """Run CHKDSK in a "split window" and report errors."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'): if global_vars['OS']['Version'] in ('8', '8.1', '10'):
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE'], '/scan', '/perf'] cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE'], '/scan', '/perf']
else: else:
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE']] cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False) out = run_program(cmd, check=False)
# retcode == 0: no issues # retcode == 0: no issues
# retcode == 1: fixed issues (also happens when chkdsk.exe is killed?) # retcode == 1: fixed issues (also happens when chkdsk.exe is killed?)
# retcode == 2: issues # retcode == 2: issues
if int(out.returncode) > 0: if int(out.returncode) > 0:
# print_error(' ERROR: CHKDSK encountered errors') # print_error(' ERROR: CHKDSK encountered errors')
raise GenericError 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(): def run_chkdsk_offline():
"""Set filesystem 'dirty bit' to force a chkdsk during next boot.""" """Set filesystem 'dirty bit' to force a chkdsk during next boot."""
cmd = [ cmd = [
'fsutil', 'dirty', 'fsutil', 'dirty',
'set', 'set',
global_vars['Env']['SYSTEMDRIVE']] global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False) out = run_program(cmd, check=False)
if int(out.returncode) > 0: if int(out.returncode) > 0:
raise GenericError raise GenericError
def run_dism(repair=False): def run_dism(repair=False):
"""Run DISM /RestoreHealth, then /CheckHealth, and then report errors.""" """Run DISM to either scan or repair component store health."""
if global_vars['OS']['Version'] in ('8', '8.1', '10'): if global_vars['OS']['Version'] in ('8', '8.1', '10'):
if repair: if repair:
# Restore Health # Restore Health
cmd = [ cmd = [
'DISM', '/Online', 'DISM', '/Online',
'/Cleanup-Image', '/RestoreHealth', '/Cleanup-Image', '/RestoreHealth',
r'/LogPath:"{LogDir}\Tools\DISM_RestoreHealth.log"'.format( r'/LogPath:"{LogDir}\Tools\DISM_RestoreHealth.log"'.format(
**global_vars), **global_vars),
'-new_console:n', '-new_console:s33V'] '-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
else: 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(): def run_kvrt():
"""Run KVRT.""" """Run KVRT."""
extract_item('KVRT', silent=True) extract_item('KVRT', silent=True)
os.makedirs(global_vars['QuarantineDir'], exist_ok=True) os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
cmd = [ cmd = [
global_vars['Tools']['KVRT'], global_vars['Tools']['KVRT'],
'-accepteula', '-dontcryptsupportinfo', '-fixednames', '-accepteula', '-dontcryptsupportinfo', '-fixednames',
'-d', global_vars['QuarantineDir'], '-d', global_vars['QuarantineDir'],
'-processlevel', '3'] '-processlevel', '3']
popen_program(cmd, pipe=False) popen_program(cmd, pipe=False)
def run_sfc_scan(): def run_sfc_scan():
"""Run SFC in a "split window" and report errors.""" """Run SFC in a "split window" and report errors."""
cmd = [ cmd = [
r'{SYSTEMROOT}\System32\sfc.exe'.format(**global_vars['Env']), r'{SYSTEMROOT}\System32\sfc.exe'.format(**global_vars['Env']),
'/scannow'] '/scannow']
out = run_program(cmd, check=False) out = run_program(cmd, check=False)
# Save stderr # Save stderr
with open(r'{LogDir}\Tools\SFC.err'.format(**global_vars), 'a') as f: with open(r'{LogDir}\Tools\SFC.err'.format(**global_vars), 'a') as f:
for line in out.stderr.decode('utf-8', 'ignore').splitlines(): for line in out.stderr.decode('utf-8', 'ignore').splitlines():
f.write(line.strip() + '\n') f.write(line.strip() + '\n')
# Save stdout # Save stdout
with open(r'{LogDir}\Tools\SFC.log'.format(**global_vars), 'a') as f: with open(r'{LogDir}\Tools\SFC.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode('utf-8', 'ignore').splitlines(): for line in out.stdout.decode('utf-8', 'ignore').splitlines():
f.write(line.strip() + '\n') f.write(line.strip() + '\n')
# Check result # Check result
log_text = out.stdout.decode('utf-8', 'ignore').replace('\0', '') 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): if re.findall(r'did\s+not\s+find\s+any\s+integrity\s+violations', log_text):
pass pass
elif re.findall(r'successfully\s+repaired\s+them', log_text): elif re.findall(r'successfully\s+repaired\s+them', log_text):
raise GenericRepair raise GenericRepair
else: else:
raise GenericError raise GenericError
def run_tdsskiller(): def run_tdsskiller():
"""Run TDSSKiller.""" """Run TDSSKiller."""
extract_item('TDSSKiller', silent=True) extract_item('TDSSKiller', silent=True)
os.makedirs(r'{QuarantineDir}\TDSSKiller'.format( os.makedirs(r'{QuarantineDir}\TDSSKiller'.format(
**global_vars), exist_ok=True) **global_vars), exist_ok=True)
cmd = [ cmd = [
global_vars['Tools']['TDSSKiller'], global_vars['Tools']['TDSSKiller'],
'-l', r'{LogDir}\Tools\TDSSKiller.log'.format(**global_vars), '-l', r'{LogDir}\Tools\TDSSKiller.log'.format(**global_vars),
'-qpath', r'{QuarantineDir}\TDSSKiller'.format(**global_vars), '-qpath', r'{QuarantineDir}\TDSSKiller'.format(**global_vars),
'-accepteula', '-accepteulaksn', '-accepteula', '-accepteulaksn',
'-dcexact', '-tdlfs'] '-dcexact', '-tdlfs']
run_program(cmd, pipe=False) run_program(cmd, pipe=False)
if __name__ == '__main__': 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 * from functions.common import *
# STATIC VARIABLES # STATIC VARIABLES
REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer' REG_MSISERVER = r'HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot\Network\MSIServer'
def disable_safemode_msi(): def disable_safemode_msi():
"""Disable MSI access under safemode.""" """Disable MSI access under safemode."""
cmd = ['reg', 'delete', REG_MSISERVER, '/f'] cmd = ['reg', 'delete', REG_MSISERVER, '/f']
run_program(cmd) run_program(cmd)
def disable_safemode(): def disable_safemode():
"""Edit BCD to remove safeboot value.""" """Edit BCD to remove safeboot value."""
cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot'] cmd = ['bcdedit', '/deletevalue', '{default}', 'safeboot']
run_program(cmd) run_program(cmd)
def enable_safemode_msi(): def enable_safemode_msi():
"""Enable MSI access under safemode.""" """Enable MSI access under safemode."""
cmd = ['reg', 'add', REG_MSISERVER, '/f'] cmd = ['reg', 'add', REG_MSISERVER, '/f']
run_program(cmd) run_program(cmd)
cmd = ['reg', 'add', REG_MSISERVER, '/ve', cmd = ['reg', 'add', REG_MSISERVER, '/ve',
'/t', 'REG_SZ', '/d', 'Service', '/f'] '/t', 'REG_SZ', '/d', 'Service', '/f']
run_program(cmd) run_program(cmd)
def enable_safemode(): def enable_safemode():
"""Edit BCD to set safeboot as default.""" """Edit BCD to set safeboot as default."""
cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network'] cmd = ['bcdedit', '/set', '{default}', 'safeboot', 'network']
run_program(cmd) run_program(cmd)
def reboot(delay=3): def reboot(delay=3):
cmd = ['shutdown', '-r', '-t', '{}'.format(delay)] cmd = ['shutdown', '-r', '-t', '{}'.format(delay)]
run_program(cmd, check=False) run_program(cmd, check=False)
if __name__ == '__main__': 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 # Wizard Kit: Functions - Setup
from functions.common import * from functions.browsers import *
from functions.json import *
from functions.update 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(): def config_classicstart():
"""Configure ClassicStart.""" """Configure ClassicStart."""
# User level, not system level # User level, not system level
cs_exe = r'{PROGRAMFILES}\Classic Shell\ClassicStartMenu.exe'.format( cs_exe = r'{PROGRAMFILES}\Classic Shell\ClassicStartMenu.exe'.format(
**global_vars['Env']) **global_vars['Env'])
skin = r'{PROGRAMFILES}\Classic Shell\Skins\Metro-Win10-Black.skin7'.format( skin = r'{PROGRAMFILES}\Classic Shell\Skins\Metro-Win10-Black.skin7'.format(
**global_vars['Env']) **global_vars['Env'])
extract_item('ClassicStartSkin', silent=True) extract_item('ClassicStartSkin', silent=True)
# Stop Classic Start # Stop Classic Start
run_program([cs_exe, '-exit'], check=False) run_program([cs_exe, '-exit'], check=False)
sleep(1) sleep(1)
kill_process('ClassicStartMenu.exe') kill_process('ClassicStartMenu.exe')
# Configure # Configure
write_registry_settings(SETTINGS_CLASSIC_START, all_users=False) write_registry_settings(SETTINGS_CLASSIC_START, all_users=False)
if global_vars['OS']['Version'] == '10' and os.path.exists(skin): if global_vars['OS']['Version'] == '10' and os.path.exists(skin):
# Enable Win10 theme if on Win10 # Enable Win10 theme if on Win10
key_path = r'Software\IvoSoft\ClassicStartMenu\Settings' key_path = r'Software\IvoSoft\ClassicStartMenu\Settings'
with winreg.OpenKey(HKCU, key_path, access=winreg.KEY_WRITE) as key: with winreg.OpenKey(HKCU, key_path, access=winreg.KEY_WRITE) as key:
winreg.SetValueEx( winreg.SetValueEx(
key, 'SkinW7', 0, winreg.REG_SZ, 'Metro-Win10-Black') key, 'SkinW7', 0, winreg.REG_SZ, 'Metro-Win10-Black')
winreg.SetValueEx(key, 'SkinVariationW7', 0, winreg.REG_SZ, '') winreg.SetValueEx(key, 'SkinVariationW7', 0, winreg.REG_SZ, '')
# Pin Browser to Start Menu (Classic) # Pin Browser to Start Menu (Classic)
firefox = r'{PROGRAMDATA}\Start Menu\Programs\Mozilla Firefox.lnk'.format( firefox = r'{PROGRAMDATA}\Start Menu\Programs\Mozilla Firefox.lnk'.format(
**global_vars['Env']) **global_vars['Env'])
chrome = r'{PROGRAMDATA}\Start Menu\Programs\Google Chrome.lnk'.format( chrome = r'{PROGRAMDATA}\Start Menu\Programs\Google Chrome.lnk'.format(
**global_vars['Env']) **global_vars['Env'])
dest_path = r'{APPDATA}\ClassicShell\Pinned'.format(**global_vars['Env']) dest_path = r'{APPDATA}\ClassicShell\Pinned'.format(**global_vars['Env'])
source = None source = None
dest = None dest = None
if os.path.exists(firefox): if os.path.exists(firefox):
source = firefox source = firefox
dest = r'{}\Mozilla Firefox.lnk'.format(dest_path) dest = r'{}\Mozilla Firefox.lnk'.format(dest_path)
elif os.path.exists(chrome): elif os.path.exists(chrome):
source = chrome source = chrome
dest = r'{}\Google Chrome.lnk'.format(dest_path) dest = r'{}\Google Chrome.lnk'.format(dest_path)
if source: if source:
try: try:
os.makedirs(dest_path, exist_ok=True) os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest) shutil.copy(source, dest)
except Exception: except Exception:
pass # Meh, it's fine without 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(): def config_explorer_system():
"""Configure Windows Explorer for all users via Registry settings.""" """Configure Windows Explorer for all users."""
write_registry_settings(SETTINGS_EXPLORER_SYSTEM, all_users=True) 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(): def config_explorer_user(setup_mode='All'):
"""Disable Windows 10 telemetry settings with O&O ShutUp10.""" """Configure Windows Explorer for current user per setup_mode."""
extract_item('ShutUp10', silent=True) settings_explorer_user = {
cmd = [ k: v for k, v in SETTINGS_EXPLORER_USER.items()
r'{BinDir}\ShutUp10\OOSU10.exe'.format(**global_vars), if setup_mode not in v.get('Invalid modes', [])
r'{BinDir}\ShutUp10\1201.cfg'.format(**global_vars), }
'/quiet'] write_registry_settings(settings_explorer_user, all_users=False)
run_program(cmd)
def config_windows_updates():
"""Configure Windows updates."""
write_registry_settings(SETTINGS_WINDOWS_UPDATES, all_users=True)
def update_clock(): def update_clock():
"""Set Timezone and sync clock.""" """Set Timezone and sync clock."""
run_program(['tzutil' ,'/s', WINDOWS_TIME_ZONE], check=False) run_program(['tzutil', '/s', WINDOWS_TIME_ZONE], check=False)
run_program(['net', 'stop', 'w32ime'], check=False) run_program(['net', 'stop', 'w32ime'], check=False)
run_program( run_program(
['w32tm', '/config', '/syncfromflags:manual', ['w32tm', '/config', '/syncfromflags:manual',
'/manualpeerlist:"us.pool.ntp.org time.nist.gov time.windows.com"', '/manualpeerlist:"us.pool.ntp.org time.nist.gov time.windows.com"',
], ],
check=False) check=False)
run_program(['net', 'start', 'w32ime'], check=False) run_program(['net', 'start', 'w32ime'], check=False)
run_program(['w32tm', '/resync', '/nowait'], check=False) run_program(['w32tm', '/resync', '/nowait'], check=False)
def write_registry_settings(settings, all_users=False): def write_registry_settings(settings, all_users=False):
"""Write registry values from custom dict of dicts.""" """Write registry values from custom dict of dicts."""
hive = HKCU hive = HKCU
if all_users: if all_users:
hive = HKLM hive = HKLM
for k, v in settings.items(): for k, v in settings.items():
# CreateKey # CreateKey
access = winreg.KEY_WRITE access = winreg.KEY_WRITE
if 'WOW64_32' in v: if 'WOW64_32' in v:
access = access | winreg.KEY_WOW64_32KEY access = access | winreg.KEY_WOW64_32KEY
winreg.CreateKeyEx(hive, k, 0, access) 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 # 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(): def install_adobe_reader():
"""Install Adobe Reader.""" """Install Adobe Reader."""
cmd = [ cmd = [
r'{BaseDir}\Installers\Extras\Office\Adobe Reader DC.exe'.format( r'{BaseDir}\Installers\Extras\Office\Adobe Reader DC.exe'.format(
**global_vars), **global_vars),
'/sAll', '/sAll',
'/msi', '/norestart', '/quiet', '/msi', '/norestart', '/quiet',
'ALLUSERS=1', 'ALLUSERS=1',
'EULA_ACCEPT=YES'] 'EULA_ACCEPT=YES']
run_program(cmd) run_program(cmd)
def install_chrome_extensions(): def install_chrome_extensions():
"""Update registry to install Google Chrome extensions for all users.""" """Install Google Chrome extensions for all users."""
write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True) write_registry_settings(SETTINGS_GOOGLE_CHROME, all_users=True)
def install_classicstart_skin(): def install_classicstart_skin():
"""Extract ClassicStart skin to installation folder.""" """Extract ClassicStart skin to installation folder."""
if global_vars['OS']['Version'] not in ('8', '8.1', '10'): if global_vars['OS']['Version'] not in ('8', '8.1', '10'):
raise UnsupportedOSError raise UnsupportedOSError
extract_item('ClassicStartSkin', silent=True) extract_item('ClassicStartSkin', silent=True)
source = r'{BinDir}\ClassicStartSkin\Metro-Win10-Black.skin7'.format( source = r'{BinDir}\ClassicStartSkin\Metro-Win10-Black.skin7'.format(
**global_vars) **global_vars)
dest_path = r'{PROGRAMFILES}\Classic Shell\Skins'.format( dest_path = r'{PROGRAMFILES}\Classic Shell\Skins'.format(
**global_vars['Env']) **global_vars['Env'])
dest = r'{}\Metro-Win10-Black.skin7'.format(dest_path) dest = r'{}\Metro-Win10-Black.skin7'.format(dest_path)
os.makedirs(dest_path, exist_ok=True) os.makedirs(dest_path, exist_ok=True)
shutil.copy(source, dest) shutil.copy(source, dest)
def install_firefox_extensions(): def install_firefox_extensions():
"""Update registry to install Firefox extensions for all users.""" """Install Firefox extensions for all users."""
dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format( dist_path = r'{PROGRAMFILES}\Mozilla Firefox\distribution\extensions'.format(
**global_vars['Env']) **global_vars['Env'])
source_path = r'{CBinDir}\FirefoxExtensions.7z'.format(**global_vars) source_path = r'{CBinDir}\FirefoxExtensions.7z'.format(**global_vars)
if not os.path.exists(source_path): if not os.path.exists(source_path):
raise FileNotFoundError raise FileNotFoundError
# Update registry # Update registry
write_registry_settings(SETTINGS_MOZILLA_FIREFOX_32, all_users=True) write_registry_settings(SETTINGS_MOZILLA_FIREFOX_32, all_users=True)
write_registry_settings(SETTINGS_MOZILLA_FIREFOX_64, all_users=True) write_registry_settings(SETTINGS_MOZILLA_FIREFOX_64, all_users=True)
# Extract extension(s) to distribution folder # Extract extension(s) to distribution folder
cmd = [ cmd = [
global_vars['Tools']['SevenZip'], 'e', '-aos', '-bso0', '-bse0', global_vars['Tools']['SevenZip'], 'e', '-aos', '-bso0', '-bse0',
'-p{ArchivePassword}'.format(**global_vars), '-p{ArchivePassword}'.format(**global_vars),
'-o{dist_path}'.format(dist_path=dist_path), '-o{dist_path}'.format(dist_path=dist_path),
source_path] source_path]
run_program(cmd) 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'): if global_vars['OS']['Version'] in ('8', '8.1', '10'):
# Modern selection main_selections.append('standard')
popen_program(r'{BaseDir}\Installers\Extras\Bundles\Modern.exe'.format(
**global_vars))
else: else:
# Legacy selection main_selections.append('standard7')
if mse: if main_selections:
cmd = r'{BaseDir}\Installers\Extras\Security'.format(**global_vars) # Only run if base and/or standard are enabled
cmd += r'\Microsoft Security Essentials.exe' cmd = r'{}\Installers\Extras\Bundles\{}.exe'.format(
popen_program(cmd) global_vars['BaseDir'],
popen_program(r'{BaseDir}\Installers\Extras\Bundles\Legacy.exe'.format( '-'.join(main_selections),
**global_vars)) )
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(): def install_vcredists():
"""Install all supported Visual C++ runtimes.""" """Install all supported Visual C++ runtimes."""
extract_item('_vcredists', silent=True) extract_item('_vcredists', silent=True)
prev_dir = os.getcwd() prev_dir = os.getcwd()
try: try:
os.chdir(r'{BinDir}\_vcredists'.format(**global_vars)) os.chdir(r'{BinDir}\_vcredists'.format(**global_vars))
except FileNotFoundError: except FileNotFoundError:
# Ignored since the loop below will report the errors # Ignored since the loop below will report the errors
pass pass
for vcr in VCR_REDISTS: for vcr in VCR_REDISTS:
try_and_print(message=vcr['Name'], function=run_program, try_and_print(message=vcr['Name'], function=run_program,
cmd=vcr['Cmd'], other_results=OTHER_RESULTS) cmd=vcr['Cmd'], other_results=OTHER_RESULTS)
os.chdir(prev_dir)
os.chdir(prev_dir)
# Misc # Misc
def open_device_manager(): 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(): def open_windows_activation():
popen_program(['slui']) popen_program(['slui'])
def open_windows_updates(): 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__': 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.data import *
from functions.disk 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): 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.""" Searches on local disks and then the WINDOWS_SERVER share."""
image = {} image = {}
imagefile = windows_version['Image File'] imagefile = windows_version['Image File']
imagename = windows_version['Image Name'] imagename = windows_version['Image Name']
# Search local source # Search local source
set_thread_error_mode(silent=True) # Prevents "No disk" popups set_thread_error_mode(silent=True) # Prevents "No disk" popups
for d in psutil.disk_partitions(): for d in psutil.disk_partitions():
for ext in ['esd', 'wim', 'swm']: for ext in ['esd', 'wim', 'swm']:
path = '{}images\{}.{}'.format(d.mountpoint, imagefile, ext) path = '{}images\{}.{}'.format(d.mountpoint, imagefile, ext)
if os.path.isfile(path) and wim_contains_image(path, imagename): if os.path.isfile(path) and wim_contains_image(path, imagename):
image['Path'] = path image['Path'] = path
image['Letter'] = d.mountpoint[:1].upper() image['Letter'] = d.mountpoint[:1].upper()
image['Local'] = True image['Local'] = True
if ext == 'swm': if ext == 'swm':
image['Glob'] = '--ref="{}*.swm"'.format(image['Path'][:-4]) image['Glob'] = '--ref="{}*.swm"'.format(image['Path'][:-4])
break break
set_thread_error_mode(silent=False) # Return to normal set_thread_error_mode(silent=False) # Return to normal
# Check for network source # Check for network source
if not image: if not image:
mount_windows_share() mount_windows_share()
if WINDOWS_SERVER['Mounted']: if WINDOWS_SERVER['Mounted']:
for ext in ['esd', 'wim', 'swm']: for ext in ['esd', 'wim', 'swm']:
path = r'\\{}\{}\images\{}.{}'.format( path = r'\\{}\{}\images\{}.{}'.format(
WINDOWS_SERVER['IP'], WINDOWS_SERVER['IP'],
WINDOWS_SERVER['Share'], WINDOWS_SERVER['Share'],
imagefile, imagefile,
ext) ext)
if os.path.isfile(path) and wim_contains_image(path, imagename): if os.path.isfile(path) and wim_contains_image(path, imagename):
image['Path'] = path image['Path'] = path
image['Letter'] = None image['Letter'] = None
image['Local'] = False image['Local'] = False
if ext == 'swm': if ext == 'swm':
image['Glob'] = '--ref="{}*.swm"'.format( image['Glob'] = '--ref="{}*.swm"'.format(
image['Path'][:-4]) image['Path'][:-4])
break 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): def format_disk(disk, use_gpt):
"""Format disk for use as a Windows OS disk.""" """Format disk for use as a Windows OS disk."""
if use_gpt: if use_gpt:
format_gpt(disk) format_gpt(disk)
else: else:
format_mbr(disk) format_mbr(disk)
def format_gpt(disk): def format_gpt(disk):
"""Format disk for use as a Windows OS disk using the GPT layout.""" """Format disk for use as a Windows OS disk using the GPT layout."""
script = [ script = [
# Partition table # Partition table
'select disk {}'.format(disk['Number']), 'select disk {}'.format(disk['Number']),
'clean', 'clean',
'convert gpt', 'convert gpt',
# System partition # System partition
# NOTE: ESP needs to be >= 260 for Advanced Format 4K disks # NOTE: ESP needs to be >= 260 for Advanced Format 4K disks
'create partition efi size=500', 'create partition efi size=500',
'format quick fs=fat32 label="System"', 'format quick fs=fat32 label="System"',
'assign letter="S"', 'assign letter="S"',
# Microsoft Reserved (MSR) partition # Microsoft Reserved (MSR) partition
'create partition msr size=128', 'create partition msr size=128',
# Windows partition # Windows partition
'create partition primary', 'create partition primary',
'format quick fs=ntfs label="Windows"', 'format quick fs=ntfs label="Windows"',
'assign letter="W"', 'assign letter="W"',
# Recovery Tools partition # Recovery Tools partition
'shrink minimum=500', 'shrink minimum=500',
'create partition primary', 'create partition primary',
'format quick fs=ntfs label="Recovery Tools"', 'format quick fs=ntfs label="Recovery Tools"',
'assign letter="T"', 'assign letter="T"',
'set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"', 'set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"',
'gpt attributes=0x8000000000000001', 'gpt attributes=0x8000000000000001',
] ]
# Run
run_diskpart(script)
# Run
run_diskpart(script)
def format_mbr(disk): def format_mbr(disk):
"""Format disk for use as a Windows OS disk using the MBR layout.""" """Format disk for use as a Windows OS disk using the MBR layout."""
script = [ script = [
# Partition table # Partition table
'select disk {}'.format(disk['Number']), 'select disk {}'.format(disk['Number']),
'clean', 'clean',
# System partition # System partition
'create partition primary size=100', 'create partition primary size=100',
'format fs=ntfs quick label="System Reserved"', 'format fs=ntfs quick label="System Reserved"',
'active', 'active',
'assign letter="S"', 'assign letter="S"',
# Windows partition # Windows partition
'create partition primary', 'create partition primary',
'format fs=ntfs quick label="Windows"', 'format fs=ntfs quick label="Windows"',
'assign letter="W"', 'assign letter="W"',
# Recovery Tools partition # Recovery Tools partition
'shrink minimum=500', 'shrink minimum=500',
'create partition primary', 'create partition primary',
'format quick fs=ntfs label="Recovery"', 'format quick fs=ntfs label="Recovery"',
'assign letter="T"', 'assign letter="T"',
'set id=27', 'set id=27',
] ]
# Run
run_diskpart(script)
# Run
run_diskpart(script)
def mount_windows_share(): def mount_windows_share():
"""Mount the Windows images share unless labeled as already mounted.""" """Mount the Windows images share unless already mounted."""
if not WINDOWS_SERVER['Mounted']: if not WINDOWS_SERVER['Mounted']:
# Mounting read-write in case a backup was done in the same session # 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 # and the server was left mounted read-write. This avoids throwing an
# error by trying to mount the same server with multiple credentials. # error by trying to mount the same server with multiple credentials.
mount_network_share(WINDOWS_SERVER, read_write=True) mount_network_share(WINDOWS_SERVER, read_write=True)
def select_windows_version(): def select_windows_version():
"""Select Windows version from a menu, returns dict.""" """Select Windows version from a menu, returns dict."""
actions = [ actions = [
{'Name': 'Main Menu', 'Letter': 'M'}, {'Name': 'Main Menu', 'Letter': 'M'},
] ]
# Menu loop # Menu loop
selection = menu_select( selection = menu_select(
title = 'Which version of Windows are we installing?', title = 'Which version of Windows are we installing?',
main_entries = WINDOWS_VERSIONS, main_entries = WINDOWS_VERSIONS,
action_entries = actions) 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): def setup_windows(windows_image, windows_version):
"""Apply a Windows image to W:""" """Apply a Windows image to W:"""
cmd = [ cmd = [
global_vars['Tools']['wimlib-imagex'], global_vars['Tools']['wimlib-imagex'],
'apply', 'apply',
windows_image['Path'], windows_image['Path'],
windows_version['Image Name'], windows_version['Image Name'],
'W:\\'] 'W:\\']
if 'Glob' in windows_image: if 'Glob' in windows_image:
cmd.extend(windows_image['Glob']) cmd.extend(windows_image['Glob'])
run_program(cmd) run_program(cmd)
def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'): def setup_windows_re(windows_version, windows_letter='W', tools_letter='T'):
"""Setup the WinRE partition.""" """Setup the WinRE partition."""
win = r'{}:\Windows'.format(windows_letter) win = r'{}:\Windows'.format(windows_letter)
winre = r'{}\System32\Recovery\WinRE.wim'.format(win) winre = r'{}\System32\Recovery\WinRE.wim'.format(win)
dest = r'{}:\Recovery\WindowsRE'.format(tools_letter) dest = r'{}:\Recovery\WindowsRE'.format(tools_letter)
# Copy WinRE.wim # Copy WinRE.wim
os.makedirs(dest, exist_ok=True) os.makedirs(dest, exist_ok=True)
shutil.copy(winre, r'{}\WinRE.wim'.format(dest)) 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'): def update_boot_partition(system_letter='S', windows_letter='W', mode='ALL'):
"""Setup the Windows boot partition.""" """Setup the Windows boot partition."""
cmd = [ cmd = [
r'{}\Windows\System32\bcdboot.exe'.format( r'{}\Windows\System32\bcdboot.exe'.format(
global_vars['Env']['SYSTEMDRIVE']), global_vars['Env']['SYSTEMDRIVE']),
r'{}:\Windows'.format(windows_letter), r'{}:\Windows'.format(windows_letter),
'/s', '{}:'.format(system_letter), '/s', '{}:'.format(system_letter),
'/f', mode] '/f', mode]
run_program(cmd) run_program(cmd)
def wim_contains_image(filename, imagename): def wim_contains_image(filename, imagename):
"""Check if an ESD/WIM contains the specified image, returns bool.""" """Check if an ESD/WIM contains the specified image, returns bool."""
cmd = [ cmd = [
global_vars['Tools']['wimlib-imagex'], global_vars['Tools']['wimlib-imagex'],
'info', 'info',
filename, filename,
imagename] imagename]
try: try:
run_program(cmd) run_program(cmd)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
return False return False
return True
return True
if __name__ == '__main__': 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.backup import *
from functions.disk import * from functions.disk import *
from functions.windows_setup 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(): def check_pe_tools():
"""Fix tool paths for WinPE layout.""" """Fix tool paths for WinPE layout."""
for k in PE_TOOLS.keys(): for k in PE_TOOLS.keys():
PE_TOOLS[k]['Path'] = r'{}\{}'.format( PE_TOOLS[k]['Path'] = r'{}\{}'.format(
global_vars['BinDir'], PE_TOOLS[k]['Path']) global_vars['BinDir'], PE_TOOLS[k]['Path'])
global_vars['Tools']['wimlib-imagex'] = re.sub( global_vars['Tools']['wimlib-imagex'] = re.sub(
r'\\x(32|64)', r'\\x(32|64)',
r'', r'',
global_vars['Tools']['wimlib-imagex'], global_vars['Tools']['wimlib-imagex'],
re.IGNORECASE) re.IGNORECASE)
def menu_backup(): def menu_backup():
"""Take backup images of partition(s) in the WIM format.""" """Take backup images of partition(s) in the WIM format."""
errors = False errors = False
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
'PathNotFoundError': 'Missing', 'PathNotFoundError': 'Missing',
}, },
'Warning': { 'Warning': {
'GenericAbort': 'Skipped', 'GenericAbort': 'Skipped',
'GenericRepair': 'Repaired', 'GenericRepair': 'Repaired',
}} }}
set_title('{}: Backup Menu'.format(KIT_NAME_FULL)) set_title('{}: Backup Menu'.format(KIT_NAME_FULL))
# Set backup prefix # Set backup prefix
clear_screen() clear_screen()
print_standard('{}\n'.format(global_vars['Title'])) print_standard('{}\n'.format(global_vars['Title']))
ticket_number = get_ticket_number() ticket_number = get_ticket_number()
if ENABLED_TICKET_NUMBERS: if ENABLED_TICKET_NUMBERS:
backup_prefix = ticket_number 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: else:
backup_prefix = get_simple_string(prompt='Enter backup name prefix') show_data(message=message, data=data, width=30)
backup_prefix = backup_prefix.replace(' ', '_') print_standard(disk['Backup Warnings'])
# Assign drive letters # Ask to proceed
try_and_print( if (not ask('Proceed with backup?')):
message = 'Assigning letters...', raise GenericAbort
function = assign_volume_letters,
other_results = other_results)
# Mount backup shares # Backup partition(s)
mount_backup_shares(read_write=True) print_info('\n\nStarting task.\n')
for par in disk['Partitions']:
# Select destination
destination = select_backup_destination(auto_select=False)
# Scan disks
result = try_and_print( result = try_and_print(
message = 'Getting disk info...', message = 'Partition {} Backup...'.format(par['Number']),
function = scan_disks, function = backup_partition,
other_results = other_results) other_results = other_results,
if result['CS']: disk = disk,
disks = result['Out'] par = par)
else: if not result['CS'] and not isinstance(result['Error'], GenericAbort):
print_error('ERROR: No disks found.') errors = True
raise GenericAbort par['Error'] = result['Error']
# Select disk to backup # Verify backup(s)
disk = select_disk('For which disk are we creating backups?', disks) if disk['Valid Partitions']:
if not disk: print_info('\n\nVerifying backup images(s)\n')
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']: for par in disk['Partitions']:
message = 'Partition {}:'.format(par['Number']) if par['Number'] in disk['Bad Partitions']:
data = par['Display String'] continue # Skip verification
if par['Number'] in disk['Bad Partitions']: result = try_and_print(
show_data(message=message, data=data, width=30, warning=True) message = 'Partition {} Image...'.format(par['Number']),
if 'Error' in par: function = verify_wim_backup,
show_data(message='', data=par['Error'], error=True) other_results = other_results,
elif par['Image Exists']: partition = par)
show_data(message=message, data=data, width=30, info=True) if not result['CS']:
else: errors = True
show_data(message=message, data=data, width=30) par['Error'] = result['Error']
print_standard(disk['Backup Warnings'])
# Ask to proceed # Print summary
if (not ask('Proceed with backup?')): if errors:
raise GenericAbort print_warning('\nErrors were encountered and are detailed below.')
for par in [p for p in disk['Partitions'] if 'Error' in p]:
# Backup partition(s) print_standard(' Partition {} Error:'.format(par['Number']))
print_info('\n\nStarting task.\n') if hasattr(par['Error'], 'stderr'):
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']]
try: try:
popen_program(cmd) par['Error'] = par['Error'].stderr.decode()
except Exception: except:
print_error('ERROR: Failed to open log.') # Deal with badly formatted error message
sleep(30) pass
pause('\nPress Enter to return to main menu... ') 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(): def menu_root():
"""Main WinPE menu.""" """Main WinPE menu."""
check_pe_tools() check_pe_tools()
menus = [ menus = [
{'Name': 'Create Backups', 'Menu': menu_backup}, {'Name': 'Create Backups', 'Menu': menu_backup},
{'Name': 'Setup Windows', 'Menu': menu_setup}, {'Name': 'Setup Windows', 'Menu': menu_setup},
{'Name': 'Misc Tools', 'Menu': menu_tools}, {'Name': 'Misc Tools', 'Menu': menu_tools},
] ]
actions = [ actions = [
{'Name': 'Command Prompt', 'Letter': 'C'}, {'Name': 'Command Prompt', 'Letter': 'C'},
{'Name': 'Reboot', 'Letter': 'R'}, {'Name': 'Reboot', 'Letter': 'R'},
{'Name': 'Shutdown', 'Letter': 'S'}, {'Name': 'Shutdown', 'Letter': 'S'},
] ]
# Main loop # Main loop
while True: while True:
set_title(KIT_NAME_FULL) set_title(KIT_NAME_FULL)
selection = menu_select( selection = menu_select(
title = 'Main Menu', title = 'Main Menu',
main_entries = menus, main_entries = menus,
action_entries = actions, action_entries = actions,
secret_exit = True) 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(): def menu_setup():
"""Format a disk (MBR/GPT), apply a Windows image, and setup boot files.""" """Format a disk, apply a Windows image, and create boot files."""
errors = False errors = False
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
'PathNotFoundError': 'Missing', 'PathNotFoundError': 'Missing',
}, },
'Warning': { 'Warning': {
'GenericAbort': 'Skipped', 'GenericAbort': 'Skipped',
'GenericRepair': 'Repaired', 'GenericRepair': 'Repaired',
}} }}
set_title('{}: Setup Menu'.format(KIT_NAME_FULL)) set_title('{}: Setup Menu'.format(KIT_NAME_FULL))
# Set ticket ID # Set ticket ID
clear_screen() clear_screen()
print_standard('{}\n'.format(global_vars['Title'])) print_standard('{}\n'.format(global_vars['Title']))
ticket_number = get_ticket_number() ticket_number = get_ticket_number()
# Select the version of Windows to apply # Select the version of Windows to apply
windows_version = select_windows_version() windows_version = select_windows_version()
# Find Windows image # Find Windows image
# NOTE: Reassign volume letters to ensure all devices are scanned # NOTE: Reassign volume letters to ensure all devices are scanned
try_and_print( try_and_print(
message = 'Assigning volume letters...', message = 'Assigning volume letters...',
function = assign_volume_letters, function = assign_volume_letters,
other_results = other_results) other_results = other_results)
windows_image = find_windows_image(windows_version) windows_image = find_windows_image(windows_version)
# Scan disks # Scan disks
result = try_and_print( result = try_and_print(
message = 'Getting disk info...', message = 'Getting disk info...',
function = scan_disks, function = scan_disks,
other_results = other_results) other_results = other_results)
if result['CS']: if result['CS']:
disks = result['Out'] disks = result['Out']
else: else:
print_error('ERROR: No disks found.') print_error('ERROR: No disks found.')
raise GenericAbort raise GenericAbort
# Select disk to use as the OS disk # Select disk to use as the OS disk
dest_disk = select_disk('To which disk are we installing Windows?', disks) dest_disk = select_disk('To which disk are we installing Windows?', disks)
if not dest_disk: if not dest_disk:
raise GenericAbort raise GenericAbort
# "Prep" disk # "Prep" disk
prep_disk_for_formatting(dest_disk) prep_disk_for_formatting(dest_disk)
# Display details for setup task # Display details for setup task
clear_screen() clear_screen()
print_info('Setup Windows - Details:\n') print_info('Setup Windows - Details:\n')
if ENABLED_TICKET_NUMBERS: if ENABLED_TICKET_NUMBERS:
show_data(message='Ticket:', data=ticket_number) show_data(message='Ticket:', data=ticket_number)
show_data(message='Installing:', data=windows_version['Name']) 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( show_data(
message = 'Boot Method:', message = 'Partition {}:'.format(par['Number']),
data = 'UEFI (GPT)' if dest_disk['Use GPT'] else 'Legacy (MBR)') data = par['Display String'],
show_data(message='Using Image:', data=windows_image['Path']) warning = True)
show_data( print_warning(dest_disk['Format Warnings'])
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'])
if (not ask('Is this correct?')): if (not ask('Is this correct?')):
raise GenericAbort raise GenericAbort
# Safety check # Safety check
print_standard('\nSAFETY CHECK') print_standard('\nSAFETY CHECK')
print_warning('All data will be DELETED from the ' print_warning('All data will be DELETED from the '
'disk and partition(s) listed above.') 'disk and partition(s) listed above.')
print_warning('This is irreversible and will lead ' print_warning('This is irreversible and will lead '
'to {CLEAR}{RED}DATA LOSS.'.format(**COLORS)) 'to {CLEAR}{RED}DATA LOSS.'.format(**COLORS))
if (not ask('Asking again to confirm, is this correct?')): if (not ask('Asking again to confirm, is this correct?')):
raise GenericAbort raise GenericAbort
# Remove volume letters so S, T, & W can be used below # Remove volume letters so S, T, & W can be used below
try_and_print( try_and_print(
message = 'Removing volume letters...', message = 'Removing volume letters...',
function = remove_volume_letters, function = remove_volume_letters,
other_results = other_results, other_results = other_results,
keep=windows_image['Letter']) keep=windows_image['Letter'])
# Assign new letter for local source if necessary # Assign new letter for local source if necessary
if windows_image['Local'] and windows_image['Letter'] in ['S', 'T', 'W']: if windows_image['Local'] and windows_image['Letter'] in ['S', 'T', 'W']:
new_letter = try_and_print( new_letter = try_and_print(
message = 'Reassigning source volume letter...', message = 'Reassigning source volume letter...',
function = reassign_volume_letter, function = reassign_volume_letter,
other_results = other_results, other_results = other_results,
letter=windows_image['Letter']) letter=windows_image['Letter'])
windows_image['Path'] = '{}{}'.format( windows_image['Path'] = '{}{}'.format(
new_letter, windows_image['Path'][1:]) new_letter, windows_image['Path'][1:])
windows_image['Letter'] = new_letter windows_image['Letter'] = new_letter
# Format and partition disk # Format and partition disk
result = try_and_print( result = try_and_print(
message = 'Formatting disk...', message = 'Formatting disk...',
function = format_disk, function = format_disk,
other_results = other_results, other_results = other_results,
disk = dest_disk, disk = dest_disk,
use_gpt = dest_disk['Use GPT']) use_gpt = dest_disk['Use GPT'])
if not result['CS']: if not result['CS']:
# We need to crash as the disk is in an unknown state # We need to crash as the disk is in an unknown state
print_error('ERROR: Failed to format disk.') print_error('ERROR: Failed to format disk.')
raise GenericAbort raise GenericAbort
# Apply Image # Apply Image
result = try_and_print( result = try_and_print(
message = 'Applying image...', message = 'Applying image...',
function = setup_windows, function = setup_windows,
other_results = other_results, other_results = other_results,
windows_image = windows_image, windows_image = windows_image,
windows_version = windows_version) windows_version = windows_version)
if not result['CS']: if not result['CS']:
# We need to crash as the disk is in an unknown state # We need to crash as the disk is in an unknown state
print_error('ERROR: Failed to apply image.') print_error('ERROR: Failed to apply image.')
raise GenericAbort raise GenericAbort
# Create Boot files # Create Boot files
try_and_print( try_and_print(
message = 'Updating boot files...', message = 'Updating boot files...',
function = update_boot_partition, function = update_boot_partition,
other_results = other_results) other_results = other_results)
# Setup WinRE # Setup WinRE
try_and_print( try_and_print(
message = 'Updating recovery tools...', message = 'Updating recovery tools...',
function = setup_windows_re, function = setup_windows_re,
other_results = other_results, other_results = other_results,
windows_version = windows_version) windows_version = windows_version)
# Copy WinPE log(s) # Copy WinPE log(s)
source = r'{}\Logs'.format(global_vars['ClientDir']) source = r'{}\Logs'.format(global_vars['ClientDir'])
dest = r'W:\{}\Logs\WinPE'.format(KIT_NAME_SHORT) dest = r'W:\{}\Logs\WinPE'.format(KIT_NAME_SHORT)
shutil.copytree(source, dest) 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(): def menu_tools():
"""Tool launcher menu.""" """Tool launcher menu."""
tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())] tools = [{'Name': k} for k in sorted(PE_TOOLS.keys())]
actions = [{'Name': 'Main Menu', 'Letter': 'M'},] actions = [{'Name': 'Main Menu', 'Letter': 'M'},]
set_title(KIT_NAME_FULL) 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(): def select_minidump_path():
"""Select BSOD minidump path from a menu.""" """Select BSOD minidump path from a menu."""
dumps = [] dumps = []
# Assign volume letters first # Assign volume letters first
assign_volume_letters() assign_volume_letters()
# Search for minidumps # Search for minidumps
set_thread_error_mode(silent=True) # Prevents "No disk" popups set_thread_error_mode(silent=True) # Prevents "No disk" popups
for d in psutil.disk_partitions(): for d in psutil.disk_partitions():
if global_vars['Env']['SYSTEMDRIVE'].upper() in d.mountpoint: if global_vars['Env']['SYSTEMDRIVE'].upper() in d.mountpoint:
# Skip RAMDisk # Skip RAMDisk
continue continue
if os.path.exists(r'{}Windows\MiniDump'.format(d.mountpoint)): if os.path.exists(r'{}Windows\MiniDump'.format(d.mountpoint)):
dumps.append({'Name': r'{}Windows\MiniDump'.format(d.mountpoint)}) dumps.append({'Name': r'{}Windows\MiniDump'.format(d.mountpoint)})
set_thread_error_mode(silent=False) # Return to normal set_thread_error_mode(silent=False) # Return to normal
# Check results before showing menu # Check results before showing menu
if len(dumps) == 0: if len(dumps) == 0:
print_error('ERROR: No BSoD / MiniDump paths found') print_error('ERROR: No BSoD / MiniDump paths found')
sleep(2) sleep(2)
return None 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__': 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 #!/bin/bash
# #
## Wizard Kit: HW Diagnostics - Menu Launcher ## Wizard Kit: HW Diagnostics Launcher
source launch-in-tmux
SESSION_NAME="hw-diags" SESSION_NAME="hw-diags"
WINDOW_NAME="Hardware Diagnostics" WINDOW_NAME="Hardware Diagnostics"
MENU="hw-diags-menu" TMUX_CMD="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" $*
launch_in_tmux "$@"

View file

@ -6,37 +6,37 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.common import * from functions.common import *
init_global_vars() init_global_vars()
if __name__ == '__main__': if __name__ == '__main__':
try:
# Prep
clear_screen()
print_standard('Hardware Diagnostics: Audio\n')
# Set volume
try: try:
# Prep run_program('amixer -q set "Master" 80% unmute'.split())
clear_screen() run_program('amixer -q set "PCM" 90% unmute'.split())
print_standard('Hardware Diagnostics: Audio\n') except subprocess.CalledProcessError:
print_error('Failed to set volume')
# Set volume # Run tests
try: for mode in ['pink', 'wav']:
run_program('amixer -q set "Master" 80% unmute'.split()) run_program(
run_program('amixer -q set "PCM" 90% unmute'.split()) cmd = 'speaker-test -c 2 -l 1 -t {}'.format(mode).split(),
except subprocess.CalledProcessError: check = False,
print_error('Failed to set volume') pipe = False)
# 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()
# 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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.hw_diags import * from functions.hw_diags import *
from functions.tmux import *
init_global_vars() init_global_vars()
if __name__ == '__main__': if __name__ == '__main__':
try: # Show menu
# Prep try:
clear_screen() 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 if DEBUG_MODE:
menu_diags(*sys.argv) # Custom major exception
print_standard(' ')
# Done print_error('Major exception')
#print_standard('\nDone.') print_warning(SUPPORT_MESSAGE)
#pause("Press Enter to exit...") print(traceback.format_exc())
exit_script() print_log(traceback.format_exc())
except SystemExit:
pass
except:
major_exception()
# 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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.network import * from functions.network import *
def check_connection(): def check_connection():
if not is_connected(): if not is_connected():
# Raise to cause NS in try_and_print() # Raise to cause NS in try_and_print()
raise Exception raise Exception
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep
clear_screen() clear_screen()
print_standard('Hardware Diagnostics: Network\n') print_standard('Hardware Diagnostics: Network\n')
# Connect # Connect
print_standard('Initializing...') print_standard('Initializing...')
connect_to_network() connect_to_network()
# Tests # Tests
try_and_print( try_and_print(
message='Network connection:', function=check_connection, cs='OK') message='Network connection:', function=check_connection, cs='OK')
show_valid_addresses() show_valid_addresses()
try_and_print(message='Internet connection:', function=ping, try_and_print(message='Internet connection:', function=ping,
addr='8.8.8.8', cs='OK') addr='8.8.8.8', cs='OK')
try_and_print(message='DNS Resolution:', function=ping, cs='OK') try_and_print(message='DNS Resolution:', function=ping, cs='OK')
try_and_print(message='Speedtest:', function=speedtest, try_and_print(message='Speedtest:', function=speedtest,
print_return=True) print_return=True)
# 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

@ -14,5 +14,6 @@ if [ ! -d "$1" ]; then
fi fi
# Run Prime95 # 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' BLUE='\033[34m'
CLEAR='\033[0m' CLEAR='\033[0m'
IFS=$'\n'
# List devices # List devices
IFS=$'\n'
for line in $(lsblk -do NAME,TRAN,SIZE,VENDOR,MODEL,SERIAL); do for line in $(lsblk -do NAME,TRAN,SIZE,VENDOR,MODEL,SERIAL); do
if [[ "${line:0:4}" == "NAME" ]]; then if [[ "${line:0:4}" == "NAME" ]]; then
echo -e "${BLUE}${line}${CLEAR}" echo -e "${BLUE}${line}${CLEAR}"
@ -15,6 +15,18 @@ for line in $(lsblk -do NAME,TRAN,SIZE,VENDOR,MODEL,SERIAL); do
done done
echo "" 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 # List partitions
for line in $(lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT); do for line in $(lsblk -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT); do
if [[ "${line:0:4}" == "NAME" ]]; then if [[ "${line:0:4}" == "NAME" ]]; then

View file

@ -105,8 +105,3 @@ echo -e "${BLUE}Drives${CLEAR}"
hw-drive-info | sed 's/^/ /' hw-drive-info | sed 's/^/ /'
echo "" 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 ## Wizard Kit: Sensor monitoring tool
import itertools WINDOW_NAME="Hardware Sensors"
import os MONITOR="hw-sensors-monitor"
import shutil
import sys
# Init # Start session
os.chdir(os.path.dirname(os.path.realpath(__file__))) tmux new-session -n "$WINDOW_NAME" "$MONITOR"
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()

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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.setup import * from functions.setup import *
init_global_vars() init_global_vars()
os.system('title {}: SW Bundle Tool'.format(KIT_NAME_FULL)) os.system('title {}: SW Bundle Tool'.format(KIT_NAME_FULL))
set_log_file('Install SW Bundle.log') set_log_file('Install SW Bundle.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
stay_awake() stay_awake()
clear_screen() clear_screen()
print_info('{}: SW Bundle Tool\n'.format(KIT_NAME_FULL)) print_info('{}: SW Bundle Tool\n'.format(KIT_NAME_FULL))
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
'FileNotFoundError': 'File not found', 'FileNotFoundError': 'File not found',
}, },
'Warning': { 'Warning': {
'GenericRepair': 'Repaired', 'GenericRepair': 'Repaired',
'UnsupportedOSError': 'Unsupported OS', 'UnsupportedOSError': 'Unsupported OS',
}} }}
answer_extensions = ask('Install Extensions?') answer_extensions = ask('Install Extensions?')
answer_adobe_reader = ask('Install Adobe Reader?') answer_vcr = ask('Install Visual C++ Runtimes?')
answer_vcr = ask('Install Visual C++ Runtimes?') answer_ninite = ask('Install Ninite Bundle?')
answer_ninite = ask('Install Ninite Bundle?') if answer_ninite and global_vars['OS']['Version'] in ['7']:
if answer_ninite and global_vars['OS']['Version'] in ['7']: # Vista is dead, not going to check for it
# Vista is dead, not going to check for it answer_mse = ask('Install MSE?')
answer_mse = ask('Install MSE?') else:
else: answer_mse = False
answer_mse = False
print_info('Installing Programs') print_info('Installing Programs')
if answer_adobe_reader: if answer_vcr:
try_and_print(message='Adobe Reader DC...', install_vcredists()
function=install_adobe_reader, other_results=other_results) if answer_ninite:
if answer_vcr: result = try_and_print(message='Ninite bundle...',
install_vcredists() function=install_ninite_bundle, cs='Started',
if answer_ninite: mse=answer_mse, other_results=other_results)
try_and_print(message='Ninite bundle...', for proc in result['Out']:
function=install_ninite_bundle, cs='Started', # Wait for all processes to finish
mse=answer_mse, other_results=other_results) proc.wait()
if answer_extensions: if answer_extensions:
wait_for_process('ninite.exe') print_info('Installing Extensions')
print_info('Installing Extensions') try_and_print(message='Classic Shell skin...',
try_and_print(message='Classic Shell skin...', function=install_classicstart_skin,
function=install_classicstart_skin, other_results=other_results)
other_results=other_results) try_and_print(message='Google Chrome extensions...',
try_and_print(message='Google Chrome extensions...', function=install_chrome_extensions)
function=install_chrome_extensions) try_and_print(message='Mozilla Firefox extensions...',
try_and_print(message='Mozilla Firefox extensions...', function=install_firefox_extensions,
function=install_firefox_extensions, other_results=other_results)
other_results=other_results) print_standard('\nDone.')
print_standard('\nDone.') exit_script()
exit_script() except SystemExit as sys_exit:
except SystemExit: exit_script(sys_exit.code)
pass except:
except: major_exception()
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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.setup import * from functions.setup import *
init_global_vars() init_global_vars()
os.system('title {}: Install Visual C++ Runtimes'.format(KIT_NAME_FULL)) os.system('title {}: Install Visual C++ Runtimes'.format(KIT_NAME_FULL))
set_log_file('Install Visual C++ Runtimes.log') set_log_file('Install Visual C++ Runtimes.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
stay_awake() stay_awake()
clear_screen() clear_screen()
print_info('{}: Install Visual C++ Runtimes\n'.format(KIT_NAME_FULL)) print_info('{}: Install Visual C++ Runtimes\n'.format(KIT_NAME_FULL))
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
}} }}
if ask('Install Visual C++ Runtimes?'): if ask('Install Visual C++ Runtimes?'):
install_vcredists() install_vcredists()
else: else:
abort() abort()
print_standard('\nDone.') print_standard('\nDone.')
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() 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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.data import * from functions.data import *
init_global_vars() init_global_vars()
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep
clear_screen() clear_screen()
print_standard('{}: Volume mount tool'.format(KIT_NAME_FULL)) print_standard('{}: Volume mount tool'.format(KIT_NAME_FULL))
# Mount volumes # Mount volumes
report = mount_volumes(all_devices=True) report = mount_volumes(all_devices=True)
# Print report # Print report
print_info('\nResults') print_info('\nResults')
for vol_name, vol_data in sorted(report.items()): for vol_name, vol_data in sorted(report.items()):
show_data(indent=4, width=20, **vol_data['show_data']) show_data(indent=4, width=20, **vol_data['show_data'])
# Done # Done
print_standard('\nDone.') print_standard('\nDone.')
if 'gui' in sys.argv: if 'gui' in sys.argv:
pause("Press Enter to exit...") pause("Press Enter to exit...")
popen_program(['nohup', 'thunar', '/media'], pipe=True) popen_program(['nohup', 'thunar', '/media'], pipe=True)
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() major_exception()
# vim: sts=2 sw=2 ts=2

View file

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

@ -9,73 +9,76 @@ import sys
# STATIC VARIABLES # STATIC VARIABLES
SCANDIR = os.getcwd() SCANDIR = os.getcwd()
USAGE = '''Usage: {script} <search-terms>... 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 This script will search all doc/docx files below the current directory for
the search-terms provided (case-insensitive).'''.format(script=__file__) the search-terms provided (case-insensitive).'''.format(script=__file__)
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.network import * from functions.network import *
init_global_vars() init_global_vars()
REGEX_DOC_FILES = re.compile(r'\.docx?$', re.IGNORECASE) REGEX_DOC_FILES = re.compile(r'\.docx?$', re.IGNORECASE)
def scan_for_docs(path): def scan_for_docs(path):
for entry in os.scandir(path): for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False): if entry.is_dir(follow_symlinks=False):
yield from scantree(entry.path) yield from scan_for_docs(entry.path)
elif entry.is_file and REGEX_DOC_FILES.search(entry.name): elif entry.is_file and REGEX_DOC_FILES.search(entry.name):
yield entry yield entry
def scan_file(file_path, search): def scan_file(file_path, search):
match = False match = False
try: try:
if entry.name.lower().endswith('.docx'): if entry.name.lower().endswith('.docx'):
result = run_program(['unzip', '-p', entry.path]) result = run_program(['unzip', '-p', entry.path])
else: else:
# Assuming .doc # Assuming .doc
result = run_program(['antiword', entry.path]) result = run_program(['antiword', entry.path])
out = result.stdout.decode() out = result.stdout.decode()
match = re.search(search, out, re.IGNORECASE) match = re.search(search, out, re.IGNORECASE)
except Exception: except Exception:
# Ignore errors since files may be corrupted # Ignore errors since files may be corrupted
pass pass
return entry.path if match else None return entry.path if match else None
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep
clear_screen() clear_screen()
terms = [re.sub(r'\s+', r'\s*', t) for t in sys.argv[1:]] terms = [re.sub(r'\s+', r'\s*', t) for t in sys.argv[1:]]
search = '({})'.format('|'.join(terms)) search = '({})'.format('|'.join(terms))
if len(sys.argv) == 1: if len(sys.argv) == 1:
# Print usage # Print usage
print_standard(USAGE) print_standard(USAGE)
else: else:
matches = [] matches = []
for entry in scan_for_docs(SCANDIR): for entry in scan_for_docs(SCANDIR):
matches.append(scan_file(entry.path, search)) matches.append(scan_file(entry.path, search))
# Strip None values (i.e. non-matching entries) # Strip None values (i.e. non-matching entries)
matches = [m for m in matches if m] matches = [m for m in matches if m]
if matches: if matches:
print_success('Found {} {}:'.format( print_success('Found {} {}:'.format(
len(matches), len(matches),
'Matches' if len(matches) > 1 else 'Match')) 'Matches' if len(matches) > 1 else 'Match'))
for match in matches: for match in matches:
print_standard(match) print_standard(match)
else: else:
print_error('No matches found.') print_error('No matches found.')
# 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,35 +4,36 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.safemode import * from functions.safemode import *
init_global_vars() init_global_vars()
os.system('title {}: SafeMode Tool'.format(KIT_NAME_FULL)) os.system('title {}: SafeMode Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__': if __name__ == '__main__':
try: try:
clear_screen() clear_screen()
print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL)) print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL))
other_results = { other_results = {
'Error': {'CalledProcessError': 'Unknown Error'}, 'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}} 'Warning': {}}
if not ask('Enable booting to SafeMode (with Networking)?'): if not ask('Enable booting to SafeMode (with Networking)?'):
abort() abort()
# Configure SafeMode # Configure SafeMode
try_and_print(message='Set BCD option...', try_and_print(message='Set BCD option...',
function=enable_safemode, other_results=other_results) function=enable_safemode, other_results=other_results)
try_and_print(message='Enable MSI in SafeMode...', try_and_print(message='Enable MSI in SafeMode...',
function=enable_safemode_msi, other_results=other_results) function=enable_safemode_msi, other_results=other_results)
# Done # Done
print_standard('\nDone.') print_standard('\nDone.')
pause('Press Enter to reboot...') pause('Press Enter to reboot...')
reboot() reboot()
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() major_exception()
# vim: sts=2 sw=2 ts=2

View file

@ -4,35 +4,36 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.safemode import * from functions.safemode import *
init_global_vars() init_global_vars()
os.system('title {}: SafeMode Tool'.format(KIT_NAME_FULL)) os.system('title {}: SafeMode Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__': if __name__ == '__main__':
try: try:
clear_screen() clear_screen()
print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL)) print_info('{}: SafeMode Tool\n'.format(KIT_NAME_FULL))
other_results = { other_results = {
'Error': {'CalledProcessError': 'Unknown Error'}, 'Error': {'CalledProcessError': 'Unknown Error'},
'Warning': {}} 'Warning': {}}
if not ask('Disable booting to SafeMode?'): if not ask('Disable booting to SafeMode?'):
abort() abort()
# Configure SafeMode # Configure SafeMode
try_and_print(message='Remove BCD option...', try_and_print(message='Remove BCD option...',
function=disable_safemode, other_results=other_results) function=disable_safemode, other_results=other_results)
try_and_print(message='Disable MSI in SafeMode...', try_and_print(message='Disable MSI in SafeMode...',
function=disable_safemode_msi, other_results=other_results) function=disable_safemode_msi, other_results=other_results)
# Done # Done
print_standard('\nDone.') print_standard('\nDone.')
pause('Press Enter to reboot...') pause('Press Enter to reboot...')
reboot() reboot()
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() 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' KIT_NAME_SHORT='WK'
SUPPORT_MESSAGE='Please let 2Shirt know by opening an issue on GitHub' SUPPORT_MESSAGE='Please let 2Shirt know by opening an issue on GitHub'
# Live Linux # Live Linux
MPRIME_LIMIT='7' # of minutes to run Prime95 during hw-diags
ROOT_PASSWORD='Abracadabra' ROOT_PASSWORD='Abracadabra'
TECH_PASSWORD='Abracadabra' TECH_PASSWORD='Abracadabra'
# Server IP addresses # Server IP addresses
OFFICE_SERVER_IP='10.0.0.10' OFFICE_SERVER_IP='10.0.0.10'
QUICKBOOKS_SERVER_IP='10.0.0.10' QUICKBOOKS_SERVER_IP='10.0.0.10'
# Time Zones # Time Zones
LINUX_TIME_ZONE='America/Denver' # See 'timedatectl list-timezones' for valid values LINUX_TIME_ZONE='America/Denver' # See 'timedatectl list-timezones' for valid values
WINDOWS_TIME_ZONE='Mountain Standard Time' # See 'tzutil /l' for valid values WINDOWS_TIME_ZONE='Mountain Standard Time' # See 'tzutil /l' for valid values
# WiFi
WIFI_SSID='SomeWiFi'
WIFI_PASSWORD='Abracadabra'
# SERVER VARIABLES # SERVER VARIABLES
## NOTE: Windows can only use one user per server. This means that if ## 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 ## one server serves multiple shares then you have to use the same
## user/password for all of those shares. ## user/password for all of those shares.
BACKUP_SERVERS = [ BACKUP_SERVERS = [
{ 'IP': '10.0.0.10', { 'IP': '10.0.0.10',
'Name': 'ServerOne', 'Name': 'ServerOne',
'Mounted': False, 'Mounted': False,
'Share': 'Backups', 'Share': 'Backups',
'User': 'restore', 'User': 'restore',
'Pass': 'Abracadabra', 'Pass': 'Abracadabra',
'RW-User': 'backup', 'RW-User': 'backup',
'RW-Pass': 'Abracadabra', 'RW-Pass': 'Abracadabra',
}, },
{ 'IP': '10.0.0.11', { 'IP': '10.0.0.11',
'Name': 'ServerTwo', 'Name': 'ServerTwo',
'Mounted': False, 'Mounted': False,
'Share': 'Backups', 'Share': 'Backups',
'User': 'restore', 'User': 'restore',
'Pass': 'Abracadabra', 'Pass': 'Abracadabra',
'RW-User': 'backup', 'RW-User': 'backup',
'RW-Pass': 'Abracadabra', 'RW-Pass': 'Abracadabra',
}, },
] ]
CRASH_SERVER = { CRASH_SERVER = {
'Name': 'CrashServer', 'Name': 'CrashServer',
'Url': '', 'Url': '',
'User': '', 'User': '',
'Pass': '', 'Pass': '',
} }
OFFICE_SERVER = { OFFICE_SERVER = {
'IP': OFFICE_SERVER_IP, 'IP': OFFICE_SERVER_IP,
'Name': 'ServerOne', 'Name': 'ServerOne',
'Mounted': False, 'Mounted': False,
'Share': 'Office', 'Share': 'Office',
'User': 'restore', 'User': 'restore',
'Pass': 'Abracadabra', 'Pass': 'Abracadabra',
'RW-User': 'backup', 'RW-User': 'backup',
'RW-Pass': 'Abracadabra', 'RW-Pass': 'Abracadabra',
} }
QUICKBOOKS_SERVER = { QUICKBOOKS_SERVER = {
'IP': QUICKBOOKS_SERVER_IP, 'IP': QUICKBOOKS_SERVER_IP,
'Name': 'ServerOne', 'Name': 'ServerOne',
'Mounted': False, 'Mounted': False,
'Share': 'QuickBooks', 'Share': 'QuickBooks',
'User': 'restore', 'User': 'restore',
'Pass': 'Abracadabra', 'Pass': 'Abracadabra',
'RW-User': 'backup', 'RW-User': 'backup',
'RW-Pass': 'Abracadabra', 'RW-Pass': 'Abracadabra',
} }
WINDOWS_SERVER = { WINDOWS_SERVER = {
'IP': '10.0.0.10', 'IP': '10.0.0.10',
'Name': 'ServerOne', 'Name': 'ServerOne',
'Mounted': False, 'Mounted': False,
'Share': 'Windows', 'Share': 'Windows',
'User': 'restore', 'User': 'restore',
'Pass': 'Abracadabra', 'Pass': 'Abracadabra',
'RW-User': 'backup', 'RW-User': 'backup',
'RW-Pass': 'Abracadabra', 'RW-Pass': 'Abracadabra',
} }
if __name__ == '__main__': 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 # Wizard Kit: Settings - Music
MUSIC_MOD = [ MUSIC_MOD = [
'104208#banana_boat.mod', '104208#banana_boat.mod',
'114971#tilbury_fair.mod', '114971#tilbury_fair.mod',
'132563#ufo_tune.mod', '132563#ufo_tune.mod',
'135906#magnetik_girl.xm', '135906#magnetik_girl.xm',
'140628#autumn_in_budapest.xm', '140628#autumn_in_budapest.xm',
'143198#summer_memories_3.xm', '143198#summer_memories_3.xm',
'144405#hillbilly_billyboy.xm', '144405#hillbilly_billyboy.xm',
'154795#4mat_-_eternity.xm', '154795#4mat_-_eternity.xm',
'155845#bookworm.mo3', '155845#bookworm.mo3',
'155914#battleofsteel.xm', '155914#battleofsteel.xm',
'158975#1_channel_moog.it', '158975#1_channel_moog.it',
'165495#trans.s3m', '165495#trans.s3m',
'168513#necros_-_introspection.s3m', '168513#necros_-_introspection.s3m',
'169628#radix_-_feng_shui_schematics.xm', '169628#radix_-_feng_shui_schematics.xm',
'175238#unknown48_-_twilight.mod', '175238#unknown48_-_twilight.mod',
'33432#ambrozia.xm', '33432#ambrozia.xm',
'33460#amigatre.mod', '33460#amigatre.mod',
'34594#CHARIOT.S3M', '34594#CHARIOT.S3M',
'34596#BUTTERFL.XM', '34596#BUTTERFL.XM',
'34654#CTGOBLIN.S3M', '34654#CTGOBLIN.S3M',
'35151#bananasplit.mod', '35151#bananasplit.mod',
'35280#DEADLOCK.XM', '35280#DEADLOCK.XM',
'38591#compo_liam.xm', '38591#compo_liam.xm',
'39987#crystald.s3m', '39987#crystald.s3m',
'40475#ELYSIUM.MOD', '40475#ELYSIUM.MOD',
'42146#enigma.mod', '42146#enigma.mod',
'42519#GHOST2.MOD', '42519#GHOST2.MOD',
'42560#GSLINGER.MOD', '42560#GSLINGER.MOD',
'42872#existing.xm', '42872#existing.xm',
'50427#nf-stven.xm', '50427#nf-stven.xm',
'51549#overture.mod', '51549#overture.mod',
'54250#SATELL.S3M', '54250#SATELL.S3M',
'54313#realmk.s3m', '54313#realmk.s3m',
'55789#scrambld.mod', '55789#scrambld.mod',
'57934#spacedeb.mod', '57934#spacedeb.mod',
'59344#stardstm.mod', '59344#stardstm.mod',
'60395#2ND_PM.S3M', '60395#2ND_PM.S3M',
'66187#external.xm', '66187#external.xm',
'66343#beek-substitutionology.it', '66343#beek-substitutionology.it',
'67561#radix-unreal_superhero.xm', '67561#radix-unreal_superhero.xm',
'70829#inside_out.s3m', '70829#inside_out.s3m',
'83779#beyond_music.mod', '83779#beyond_music.mod',
] ]
MUSIC_SNES = [ MUSIC_SNES = [
'actr', 'actr',
'crock', 'crock',
'ct', 'ct',
'dkc', 'dkc',
'dkq', 'dkq',
'ff6', 'ff6',
'fz', 'fz',
'loz3', 'loz3',
'mmx', 'mmx',
'ptws', 'ptws',
'scv4', 'scv4',
'sf', 'sf',
'sf2', 'sf2',
'sgng', 'sgng',
'smk', 'smk',
'smw', 'smw',
'yi', 'yi',
'zamn' 'zamn'
] ]
if __name__ == '__main__': 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 = { SOURCE_URLS = {
'Adobe Reader DC': 'http://ardownload.adobe.com/pub/adobe/reader/win/AcrobatDC/1801120058/AcroRdrDC1801120058_en_US.exe', 'Adobe Reader DC': 'http://ardownload.adobe.com/pub/adobe/reader/win/AcrobatDC/1901020098/AcroRdrDC1901020098_en_US.exe',
'AdwCleaner': 'https://downloads.malwarebytes.com/file/adwcleaner', 'AdwCleaner': 'https://downloads.malwarebytes.com/file/adwcleaner',
'AIDA64': 'http://download.aida64.com/aida64engineer597.zip', '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', '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', 'Autoruns': 'https://download.sysinternals.com/files/Autoruns.zip',
'BleachBit': 'https://download.bleachbit.org/BleachBit-2.0-portable.zip', 'BleachBit': 'https://download.bleachbit.org/BleachBit-2.0-portable.zip',
'BlueScreenView32': 'http://www.nirsoft.net/utils/bluescreenview.zip', 'BlueScreenView32': 'http://www.nirsoft.net/utils/bluescreenview.zip',
'BlueScreenView64': 'http://www.nirsoft.net/utils/bluescreenview-x64.zip', 'BlueScreenView64': 'http://www.nirsoft.net/utils/bluescreenview-x64.zip',
'Caffeine': 'http://www.zhornsoftware.co.uk/caffeine/caffeine.zip', 'Caffeine': 'http://www.zhornsoftware.co.uk/caffeine/caffeine.zip',
'ClassicStartSkin': 'http://www.classicshell.net/forum/download/file.php?id=3001&sid=9a195960d98fd754867dcb63d9315335', 'ClassicStartSkin': 'http://www.classicshell.net/forum/download/file.php?id=3001&sid=9a195960d98fd754867dcb63d9315335',
'Du': 'https://download.sysinternals.com/files/DU.zip', 'Du': 'https://download.sysinternals.com/files/DU.zip',
'ERUNT': 'http://www.aumha.org/downloads/erunt.zip', 'ERUNT': 'http://www.aumha.org/downloads/erunt.zip',
'Everything32': 'https://www.voidtools.com/Everything-1.4.1.895.x86.zip', 'Everything32': 'https://www.voidtools.com/Everything-1.4.1.935.x86.en-US.zip',
'Everything64': 'https://www.voidtools.com/Everything-1.4.1.895.x64.zip', 'Everything64': 'https://www.voidtools.com/Everything-1.4.1.935.x64.en-US.zip',
'FastCopy': 'http://ftp.vector.co.jp/70/64/2323/FastCopy354_installer.zip', 'FastCopy': 'https://fastcopy.jp/archive/FastCopy380_installer.exe',
'Firefox uBO': 'https://addons.mozilla.org/firefox/downloads/file/1056733/ublock_origin-1.16.20-an+fx.xpi', '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', 'HitmanPro32': 'https://dl.surfright.nl/HitmanPro.exe',
'HitmanPro64': 'https://dl.surfright.nl/HitmanPro_x64.exe', 'HitmanPro64': 'https://dl.surfright.nl/HitmanPro_x64.exe',
'HWiNFO': 'http://app.oldfoss.com:81/download/HWiNFO/hwi_588.zip', 'HWiNFO': 'http://files2.majorgeeks.com/377527622c5325acc1cb937fb149d0de922320c0/systeminfo/hwi_602.zip',
'Intel SSD Toolbox': r'https://downloadmirror.intel.com/27656/eng/Intel%20SSD%20Toolbox%20-%20v3.5.2.exe', 'Intel SSD Toolbox': r'https://downloadmirror.intel.com/28593/eng/Intel%20SSD%20Toolbox%20-%20v3.5.9.exe',
'IOBit_Uninstaller': 'https://portableapps.duckduckgo.com/IObitUninstallerPortable_7.5.0.7.paf.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', 'KVRT': 'http://devbuilds.kaspersky-labs.com/devbuilds/KVRT/latest/full/KVRT.exe',
'Macs Fan Control': 'https://www.crystalidea.com/downloads/macsfancontrol_setup.exe', 'LibreOffice': 'https://download.documentfoundation.org/libreoffice/stable/6.2.4/win/x86_64/LibreOffice_6.2.4_Win_x64.msi',
'NirCmd32': 'https://www.nirsoft.net/utils/nircmd.zip', 'Macs Fan Control': 'https://www.crystalidea.com/downloads/macsfancontrol_setup.exe',
'NirCmd64': 'https://www.nirsoft.net/utils/nircmd-x64.zip', 'NirCmd32': 'https://www.nirsoft.net/utils/nircmd.zip',
'NotepadPlusPlus': 'https://notepad-plus-plus.org/repository/7.x/7.5.8/npp.7.5.8.bin.minimalist.7z', 'NirCmd64': 'https://www.nirsoft.net/utils/nircmd-x64.zip',
'Office Deployment Tool 2016': 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_10810.33603.exe', 'NotepadPlusPlus': 'https://notepad-plus-plus.org/repository/7.x/7.6.4/npp.7.6.4.bin.minimalist.7z',
'ProduKey32': 'http://www.nirsoft.net/utils/produkey.zip', 'Office Deployment Tool': 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_11509-33604.exe',
'ProduKey64': 'http://www.nirsoft.net/utils/produkey-x64.zip', 'ProduKey32': 'http://www.nirsoft.net/utils/produkey.zip',
'PuTTY': 'https://the.earth.li/~sgtatham/putty/latest/w32/putty.zip', 'ProduKey64': 'http://www.nirsoft.net/utils/produkey-x64.zip',
'RKill': 'https://www.bleepingcomputer.com/download/rkill/dl/10/', 'PuTTY': 'https://the.earth.li/~sgtatham/putty/latest/w32/putty.zip',
'Samsung Magician': 'https://s3.ap-northeast-2.amazonaws.com/global.semi.static/SAMSUNG_SSD_v5_2_1_180523/CD0CFAC4675B9E502899B41BE00525C3909ECE3AD57CC1A2FB6B74A766B2A1EA/Samsung_Magician_Installer.zip', 'RKill': 'https://www.bleepingcomputer.com/download/rkill/dl/10/',
'SDIO Themes': 'http://snappy-driver-installer.org/downloads/SDIO_Themes.zip', 'Samsung Magician': 'https://s3.ap-northeast-2.amazonaws.com/global.semi.static/SAMSUNG_SSD_v5_3_0_181121/CD0C7CC1BE00525FAC4675B9E502899B41D5C3909ECE3AA2FB6B74A766B2A1EA/Samsung_Magician_Installer.zip',
'SDIO Torrent': 'http://snappy-driver-installer.org/downloads/SDIO_Update.torrent', 'SDIO Themes': 'http://snappy-driver-installer.org/downloads/SDIO_Themes.zip',
'TDSSKiller': 'https://media.kaspersky.com/utilities/VirusUtilities/EN/tdsskiller.exe', 'SDIO Torrent': 'http://snappy-driver-installer.org/downloads/SDIO_Update.torrent',
'TestDisk': 'https://www.cgsecurity.org/testdisk-7.1-WIP.win.zip', 'TDSSKiller': 'https://media.kaspersky.com/utilities/VirusUtilities/EN/tdsskiller.exe',
'wimlib32': 'https://wimlib.net/downloads/wimlib-1.12.0-windows-i686-bin.zip', 'TestDisk': 'https://www.cgsecurity.org/testdisk-7.1-WIP.win.zip',
'wimlib64': 'https://wimlib.net/downloads/wimlib-1.12.0-windows-x86_64-bin.zip', 'wimlib32': 'https://wimlib.net/downloads/wimlib-1.13.1-windows-i686-bin.zip',
'Winapp2': 'https://github.com/MoscaDotTo/Winapp2/archive/master.zip', 'wimlib64': 'https://wimlib.net/downloads/wimlib-1.13.1-windows-x86_64-bin.zip',
'WizTree': 'https://antibody-software.com/files/wiztree_3_26_portable.zip', 'Winapp2': 'https://github.com/MoscaDotTo/Winapp2/archive/master.zip',
'XMPlay 7z': 'https://support.xmplay.com/files/16/xmp-7z.zip?v=800962', 'WizTree': 'https://antibody-software.com/files/wiztree_3_28_portable.zip',
'XMPlay Game': 'https://support.xmplay.com/files/12/xmp-gme.zip?v=515637', 'XMPlay 7z': 'https://support.xmplay.com/files/16/xmp-7z.zip?v=800962',
'XMPlay RAR': 'https://support.xmplay.com/files/16/xmp-rar.zip?v=409646', 'XMPlay Game': 'https://support.xmplay.com/files/12/xmp-gme.zip?v=515637',
'XMPlay WAModern': 'https://support.xmplay.com/files/10/WAModern.zip?v=207099', 'XMPlay RAR': 'https://support.xmplay.com/files/16/xmp-rar.zip?v=409646',
'XMPlay': 'https://support.xmplay.com/files/20/xmplay383.zip?v=298195', 'XMPlay WAModern': 'https://support.xmplay.com/files/10/WAModern.zip?v=207099',
'XYplorerFree': 'https://www.xyplorer.com/download/xyplorer_free_noinstall.zip', 'XMPlay': 'https://support.xmplay.com/files/20/xmplay383.zip?v=298195',
} 'XYplorerFree': 'https://www.xyplorer.com/download/xyplorer_free_noinstall.zip',
}
VCREDIST_SOURCES = { VCREDIST_SOURCES = {
'2010sp1': { '2010sp1': {
'32': 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe', '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', '64': 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe',
}, },
'2012u4': { '2012u4': {
'32': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe', '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', '64': 'https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe',
}, },
'2013': { '2013': {
'32': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe', '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', '64': 'https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x64.exe',
}, },
'2017': { '2017': {
'32': 'https://aka.ms/vs/15/release/vc_redist.x86.exe', '32': 'https://aka.ms/vs/15/release/vc_redist.x86.exe',
'64': 'https://aka.ms/vs/15/release/vc_redist.x64.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 = { NINITE_SOURCES = {
'Bundles': { 'Bundles': {
'Legacy.exe': '.net4.7.2-7zip-chrome-firefox-vlc', 'base.exe': '.net4.7.2-7zip-vlc',
'Modern.exe': '.net4.7.2-7zip-chrome-classicstart-firefox-vlc', 'base-standard.exe': '.net4.7.2-7zip-chrome-classicstart-firefox-sumatrapdf-vlc',
}, 'base-standard7.exe': '.net4.7.2-7zip-chrome-firefox-sumatrapdf-vlc',
'Audio-Video': { 'standard.exe': 'chrome-classicstart-firefox-sumatrapdf',
'AIMP.exe': 'aimp', 'standard7.exe': 'chrome-firefox-sumatrapdf',
'Audacity.exe': 'audacity', },
'CCCP.exe': 'cccp', 'Audio-Video': {
'Foobar2000.exe': 'foobar', 'AIMP.exe': 'aimp',
'GOM.exe': 'gom', 'Audacity.exe': 'audacity',
'HandBrake.exe': 'handbrake', 'CCCP.exe': 'cccp',
'iTunes.exe': 'itunes', 'Foobar2000.exe': 'foobar',
'K-Lite Codecs.exe': 'klitecodecs', 'GOM.exe': 'gom',
'MediaMonkey.exe': 'mediamonkey', 'HandBrake.exe': 'handbrake',
'MusicBee.exe': 'musicbee', 'iTunes.exe': 'itunes',
'Spotify.exe': 'spotify', 'K-Lite Codecs.exe': 'klitecodecs',
'VLC.exe': 'vlc', 'MediaMonkey.exe': 'mediamonkey',
'Winamp.exe': 'winamp', 'MusicBee.exe': 'musicbee',
}, 'Spotify.exe': 'spotify',
'Cloud Storage': { 'VLC.exe': 'vlc',
'Dropbox.exe': 'dropbox', 'Winamp.exe': 'winamp',
'Google Backup & Sync.exe': 'googlebackupandsync', },
'Mozy.exe': 'mozy', 'Cloud Storage': {
'OneDrive.exe': 'onedrive', 'Dropbox.exe': 'dropbox',
'SugarSync.exe': 'sugarsync', 'Google Backup & Sync.exe': 'googlebackupandsync',
}, 'Mozy.exe': 'mozy',
'Communication': { 'OneDrive.exe': 'onedrive',
'Discord': 'discord', 'SugarSync.exe': 'sugarsync',
'Pidgin.exe': 'pidgin', },
'Skype.exe': 'skype', 'Communication': {
'Trillian.exe': 'trillian', 'Discord.exe': 'discord',
}, 'Pidgin.exe': 'pidgin',
'Compression': { 'Skype.exe': 'skype',
'7-Zip.exe': '7zip', 'Trillian.exe': 'trillian',
'PeaZip.exe': 'peazip', },
'WinRAR.exe': 'winrar', 'Compression': {
}, '7-Zip.exe': '7zip',
'Developer': { 'PeaZip.exe': 'peazip',
'Eclipse.exe': 'eclipse', 'WinRAR.exe': 'winrar',
'JDK 8.exe': 'jdk8', },
'JDK 8 (x64).exe': 'jdkx8', 'Developer': {
'Notepad++.exe': 'notepadplusplus', 'Eclipse.exe': 'eclipse',
'PuTTY.exe': 'putty', 'Notepad++.exe': 'notepadplusplus',
'Python 2.exe': 'python', 'PuTTY.exe': 'putty',
'Visual Studio Code.exe': 'vscode', 'Python 2.exe': 'python',
'WinMerge.exe': 'winmerge', 'Visual Studio Code.exe': 'vscode',
'WinSCP.exe': 'winscp', 'WinMerge.exe': 'winmerge',
}, 'WinSCP.exe': 'winscp',
'File Sharing': { },
'qBittorrent.exe': 'qbittorrent', 'File Sharing': {
}, 'qBittorrent.exe': 'qbittorrent',
'Image-Photo': { },
'Blender.exe': 'blender', 'Image-Photo': {
'FastStone.exe': 'faststone', 'Blender.exe': 'blender',
'GIMP.exe': 'gimp', 'FastStone.exe': 'faststone',
'Greenshot.exe': 'greenshot', 'GIMP.exe': 'gimp',
'Inkscape.exe': 'inkscape', 'Greenshot.exe': 'greenshot',
'IrfanView.exe': 'irfanview', 'Inkscape.exe': 'inkscape',
'Krita.exe': 'krita', 'IrfanView.exe': 'irfanview',
'Paint.NET.exe': 'paint.net', 'Krita.exe': 'krita',
'ShareX.exe': 'sharex', 'Paint.NET.exe': 'paint.net',
'XnView.exe': 'xnview', 'ShareX.exe': 'sharex',
}, 'XnView.exe': 'xnview',
'Misc': { },
'Evernote.exe': 'evernote', 'Misc': {
'Everything.exe': 'everything', 'Evernote.exe': 'evernote',
'KeePass 2.exe': 'keepass2', 'Everything.exe': 'everything',
'Google Earth.exe': 'googleearth', 'KeePass 2.exe': 'keepass2',
'NV Access.exe': 'nvda', 'Google Earth.exe': 'googleearth',
'Steam.exe': 'steam', 'NV Access.exe': 'nvda',
}, 'Steam.exe': 'steam',
'Office': { },
'CutePDF.exe': 'cutepdf', 'Office': {
'Foxit Reader.exe': 'foxit', 'CutePDF.exe': 'cutepdf',
'LibreOffice.exe': 'libreoffice', 'Foxit Reader.exe': 'foxit',
'OpenOffice.exe': 'openoffice', 'LibreOffice.exe': 'libreoffice',
'PDFCreator.exe': 'pdfcreator', 'OpenOffice.exe': 'openoffice',
'SumatraPDF.exe': 'sumatrapdf', 'PDFCreator.exe': 'pdfcreator',
'Thunderbird.exe': 'thunderbird', 'SumatraPDF.exe': 'sumatrapdf',
}, 'Thunderbird.exe': 'thunderbird',
'Runtimes': { },
'Adobe Air.exe': 'air', 'Runtimes': {
'dotNET.exe': '.net4.7.2', 'Adobe Air.exe': 'air',
'Java 8.exe': 'java8', 'dotNET.exe': '.net4.7.2',
'Shockwave.exe': 'shockwave', 'Shockwave.exe': 'shockwave',
'Silverlight.exe': 'silverlight', 'Silverlight.exe': 'silverlight',
}, },
'Security': { 'Security': {
'Avast.exe': 'avast', 'Avast.exe': 'avast',
'AVG.exe': 'avg', 'AVG.exe': 'avg',
'Avira.exe': 'avira', 'Avira.exe': 'avira',
'Microsoft Security Essentials.exe': 'essentials', 'Microsoft Security Essentials.exe': 'essentials',
'Malwarebytes Anti-Malware.exe': 'malwarebytes', 'Malwarebytes Anti-Malware.exe': 'malwarebytes',
'Spybot 2.exe': 'spybot2', 'Spybot 2.exe': 'spybot2',
'SUPERAntiSpyware.exe': 'super', 'SUPERAntiSpyware.exe': 'super',
}, },
'Utilities': { 'Utilities': {
'CDBurnerXP.exe': 'cdburnerxp', 'CDBurnerXP.exe': 'cdburnerxp',
'Classic Start.exe': 'classicstart', 'Classic Start.exe': 'classicstart',
'Glary Utilities.exe': 'glary', 'Glary Utilities.exe': 'glary',
'ImgBurn.exe': 'imgburn', 'ImgBurn.exe': 'imgburn',
'InfraRecorder.exe': 'infrarecorder', 'InfraRecorder.exe': 'infrarecorder',
'Launchy.exe': 'launchy', 'Launchy.exe': 'launchy',
'RealVNC.exe': 'realvnc', 'RealVNC.exe': 'realvnc',
'Revo Uninstaller.exe': 'revo', 'Revo Uninstaller.exe': 'revo',
'TeamViewer 13.exe': 'teamviewer13', 'TeamViewer 14.exe': 'teamviewer14',
'TeraCopy.exe': 'teracopy', 'TeraCopy.exe': 'teracopy',
'WinDirStat.exe': 'windirstat', 'WinDirStat.exe': 'windirstat',
}, },
'Web Browsers': { 'Web Browsers': {
'Google Chrome.exe': 'chrome', 'Google Chrome.exe': 'chrome',
'Mozilla Firefox.exe': 'firefox', 'Mozilla Firefox.exe': 'firefox',
'Opera Chromium.exe': 'operaChromium', 'Opera Chromium.exe': 'operaChromium',
}, },
} }
RST_SOURCES = { RST_SOURCES = {
#SetupRST_12.0.exe : Removed from download center? #SetupRST_12.0.exe : Removed from download center?
#SetupRST_12.5.exe : Removed from download center? #SetupRST_12.5.exe : Removed from download center?
#SetupRST_12.8.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_12.9.exe': 'https://downloadmirror.intel.com/23496/eng/SetupRST.exe',
#SetupRST_13.x.exe : Broken, doesn't support > .NET 4.5 #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.0.exe': 'https://downloadmirror.intel.com/25091/eng/SetupRST.exe',
'SetupRST_14.8.exe': 'https://downloadmirror.intel.com/26759/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.8.exe': 'https://downloadmirror.intel.com/27442/eng/SetupRST.exe',
'SetupRST_15.9.exe': 'https://downloadmirror.intel.com/27400/eng/SetupRST.exe', 'SetupRST_15.9.exe': 'https://downloadmirror.intel.com/28656/eng/SetupRST.exe',
'SetupRST_16.0.exe': 'https://downloadmirror.intel.com/27681/eng/SetupRST.exe', #SetupRST_16.0.exe : Deprecated by Intel
'SetupRST_16.5.exe': 'https://downloadmirror.intel.com/27984/eng/SetupRST.exe', #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__': 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=4 sw=4 ts=4 tw=0 nowrap

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 # Wizard Kit: Settings - Tools
TOOLS = { TOOLS = {
# NOTE: BinDir will be prepended to these paths at runtime # NOTE: BinDir will be prepended to these paths at runtime
'AIDA64': { 'AIDA64': {
'32': r'AIDA64\aida64.exe'}, '32': r'AIDA64\aida64.exe'},
'AutoRuns': { 'AutoRuns': {
'32': r'Autoruns\autoruns.exe', '32': r'Autoruns\autoruns.exe',
'64': r'Autoruns\autoruns64.exe'}, '64': r'Autoruns\autoruns64.exe'},
'BleachBit': { 'BleachBit': {
'32': r'BleachBit\bleachbit_console.exe'}, '32': r'BleachBit\bleachbit_console.exe'},
'Caffeine': { 'Caffeine': {
'32': r'Caffeine\caffeine.exe'}, '32': r'Caffeine\caffeine.exe'},
'Du': { 'Du': {
'32': r'Du\du.exe', '32': r'Du\du.exe',
'64': r'Du\du64.exe'}, '64': r'Du\du64.exe'},
'ERUNT': { 'ERUNT': {
'32': r'ERUNT\ERUNT.EXE'}, '32': r'ERUNT\ERUNT.EXE'},
'Everything': { 'Everything': {
'32': r'Everything\Everything.exe', '32': r'Everything\Everything.exe',
'64': r'Everything\Everything64.exe'}, '64': r'Everything\Everything64.exe'},
'FastCopy': { 'FastCopy': {
'32': r'FastCopy\FastCopy.exe', '32': r'FastCopy\FastCopy.exe',
'64': r'FastCopy\FastCopy64.exe'}, '64': r'FastCopy\FastCopy64.exe'},
'HitmanPro': { 'HitmanPro': {
'32': r'HitmanPro\HitmanPro.exe', '32': r'HitmanPro\HitmanPro.exe',
'64': r'HitmanPro\HitmanPro64.exe'}, '64': r'HitmanPro\HitmanPro64.exe'},
'HWiNFO': { 'HWiNFO': {
'32': r'HWiNFO\HWiNFO.exe', '32': r'HWiNFO\HWiNFO.exe',
'64': r'HWiNFO\HWiNFO64.exe'}, '64': r'HWiNFO\HWiNFO64.exe'},
'KVRT': { 'KVRT': {
'32': r'KVRT\KVRT.exe'}, '32': r'KVRT\KVRT.exe'},
'NirCmd': { 'NirCmd': {
'32': r'NirCmd\nircmdc.exe', '32': r'NirCmd\nircmdc.exe',
'64': r'NirCmd\nircmdc64.exe'}, '64': r'NirCmd\nircmdc64.exe'},
'NotepadPlusPlus': { 'NotepadPlusPlus': {
'32': r'NotepadPlusPlus\notepadplusplus.exe'}, '32': r'NotepadPlusPlus\notepadplusplus.exe'},
'ProduKey': { 'ProduKey': {
'32': r'ProduKey\ProduKey.exe', '32': r'ProduKey\ProduKey.exe',
'64': r'ProduKey\ProduKey64.exe'}, '64': r'ProduKey\ProduKey64.exe'},
'RKill': { 'RKill': {
'32': r'RKill\RKill.exe'}, '32': r'RKill\RKill.exe'},
'SevenZip': { 'SevenZip': {
'32': r'7-Zip\7za.exe', '32': r'7-Zip\7za.exe',
'64': r'7-Zip\7za64.exe'}, '64': r'7-Zip\7za64.exe'},
'TDSSKiller': { 'TDSSKiller': {
'32': r'TDSSKiller\TDSSKiller.exe'}, '32': r'TDSSKiller\TDSSKiller.exe'},
'wimlib-imagex': { 'wimlib-imagex': {
'32': r'wimlib\x32\wimlib-imagex.exe', '32': r'wimlib\x32\wimlib-imagex.exe',
'64': r'wimlib\x64\wimlib-imagex.exe'}, '64': r'wimlib\x64\wimlib-imagex.exe'},
'XMPlay': { 'XMPlay': {
'32': r'XMPlay\xmplay.exe'}, '32': r'XMPlay\xmplay.exe'},
} }
if __name__ == '__main__': 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 = { WINDOWS_BUILDS = {
# Build Version Release Codename Marketing Name Notes # Build, Version, Release, Codename, Marketing Name, Notes
'6000': ( 'Vista', 'RTM', 'Longhorn', None, 'unsupported'), '6000': ('Vista', 'RTM', 'Longhorn', None, 'unsupported'),
'6000': ( 'Vista', 'RTM', 'Longhorn', None, 'unsupported'), '6001': ('Vista', 'SP1', 'Longhorn', None, 'unsupported'),
'6001': ( 'Vista', 'SP1', 'Longhorn', None, 'unsupported'), '6002': ('Vista', 'SP2', 'Longhorn', None, 'unsupported'),
'6002': ( 'Vista', 'SP2', 'Longhorn', None, 'unsupported'),
'7600': ( '7', 'RTM', 'Vienna', None, 'unsupported'), '7600': ('7', 'RTM', 'Vienna', None, 'unsupported'),
'7601': ( '7', 'SP1', 'Vienna', None, 'outdated'), '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 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': ('8', 'RTM', None, None, 'unsupported'),
'9200': ( '8.1', None, 'Blue', None, 'outdated'), '9200': ('8.1', None, 'Blue', None, 'outdated'),
'9600': ( '8.1', None, 'Update', None, None), '9600': ('8.1', None, 'Update', None, None),
'9841': ( '10', None, 'Threshold 1', None, 'preview build'), '9841': ('10', None, 'Threshold 1', None, 'preview build'),
'9860': ( '10', None, 'Threshold 1', None, 'preview build'), '9860': ('10', None, 'Threshold 1', None, 'preview build'),
'9879': ( '10', None, 'Threshold 1', None, 'preview build'), '9879': ('10', None, 'Threshold 1', None, 'preview build'),
'9926': ( '10', None, 'Threshold 1', None, 'preview build'), '9926': ('10', None, 'Threshold 1', None, 'preview build'),
'10041': ( '10', None, 'Threshold 1', None, 'preview build'), '10041': ('10', None, 'Threshold 1', None, 'preview build'),
'10049': ( '10', None, 'Threshold 1', None, 'preview build'), '10049': ('10', None, 'Threshold 1', None, 'preview build'),
'10061': ( '10', None, 'Threshold 1', None, 'preview build'), '10061': ('10', None, 'Threshold 1', None, 'preview build'),
'10074': ( '10', None, 'Threshold 1', None, 'preview build'), '10074': ('10', None, 'Threshold 1', None, 'preview build'),
'10122': ( '10', None, 'Threshold 1', None, 'preview build'), '10122': ('10', None, 'Threshold 1', None, 'preview build'),
'10130': ( '10', None, 'Threshold 1', None, 'preview build'), '10130': ('10', None, 'Threshold 1', None, 'preview build'),
'10158': ( '10', None, 'Threshold 1', None, 'preview build'), '10158': ('10', None, 'Threshold 1', None, 'preview build'),
'10159': ( '10', None, 'Threshold 1', None, 'preview build'), '10159': ('10', None, 'Threshold 1', None, 'preview build'),
'10162': ( '10', None, 'Threshold 1', None, 'preview build'), '10162': ('10', None, 'Threshold 1', None, 'preview build'),
'10166': ( '10', None, 'Threshold 1', None, 'preview build'), '10166': ('10', None, 'Threshold 1', None, 'preview build'),
'10240': ( '10', 'v1507', 'Threshold 1', None, 'unsupported'), '10240': ('10', 'v1507', 'Threshold 1', None, 'unsupported'),
'10525': ( '10', None, 'Threshold 2', None, 'preview build'), '10525': ('10', None, 'Threshold 2', None, 'preview build'),
'10532': ( '10', None, 'Threshold 2', None, 'preview build'), '10532': ('10', None, 'Threshold 2', None, 'preview build'),
'10547': ( '10', None, 'Threshold 2', None, 'preview build'), '10547': ('10', None, 'Threshold 2', None, 'preview build'),
'10565': ( '10', None, 'Threshold 2', None, 'preview build'), '10565': ('10', None, 'Threshold 2', None, 'preview build'),
'10576': ( '10', None, 'Threshold 2', None, 'preview build'), '10576': ('10', None, 'Threshold 2', None, 'preview build'),
'10586': ( '10', 'v1511', 'Threshold 2', 'November Update', 'unsupported'), '10586': ('10', 'v1511', 'Threshold 2', 'November Update', 'unsupported'),
'11082': ( '10', None, 'Redstone 1', None, 'preview build'), '11082': ('10', None, 'Redstone 1', None, 'preview build'),
'11099': ( '10', None, 'Redstone 1', None, 'preview build'), '11099': ('10', None, 'Redstone 1', None, 'preview build'),
'11102': ( '10', None, 'Redstone 1', None, 'preview build'), '11102': ('10', None, 'Redstone 1', None, 'preview build'),
'14251': ( '10', None, 'Redstone 1', None, 'preview build'), '14251': ('10', None, 'Redstone 1', None, 'preview build'),
'14257': ( '10', None, 'Redstone 1', None, 'preview build'), '14257': ('10', None, 'Redstone 1', None, 'preview build'),
'14271': ( '10', None, 'Redstone 1', None, 'preview build'), '14271': ('10', None, 'Redstone 1', None, 'preview build'),
'14279': ( '10', None, 'Redstone 1', None, 'preview build'), '14279': ('10', None, 'Redstone 1', None, 'preview build'),
'14291': ( '10', None, 'Redstone 1', None, 'preview build'), '14291': ('10', None, 'Redstone 1', None, 'preview build'),
'14295': ( '10', None, 'Redstone 1', None, 'preview build'), '14295': ('10', None, 'Redstone 1', None, 'preview build'),
'14316': ( '10', None, 'Redstone 1', None, 'preview build'), '14316': ('10', None, 'Redstone 1', None, 'preview build'),
'14328': ( '10', None, 'Redstone 1', None, 'preview build'), '14328': ('10', None, 'Redstone 1', None, 'preview build'),
'14332': ( '10', None, 'Redstone 1', None, 'preview build'), '14332': ('10', None, 'Redstone 1', None, 'preview build'),
'14342': ( '10', None, 'Redstone 1', None, 'preview build'), '14342': ('10', None, 'Redstone 1', None, 'preview build'),
'14352': ( '10', None, 'Redstone 1', None, 'preview build'), '14352': ('10', None, 'Redstone 1', None, 'preview build'),
'14361': ( '10', None, 'Redstone 1', None, 'preview build'), '14361': ('10', None, 'Redstone 1', None, 'preview build'),
'14366': ( '10', None, 'Redstone 1', None, 'preview build'), '14366': ('10', None, 'Redstone 1', None, 'preview build'),
'14367': ( '10', None, 'Redstone 1', None, 'preview build'), '14367': ('10', None, 'Redstone 1', None, 'preview build'),
'14371': ( '10', None, 'Redstone 1', None, 'preview build'), '14371': ('10', None, 'Redstone 1', None, 'preview build'),
'14372': ( '10', None, 'Redstone 1', None, 'preview build'), '14372': ('10', None, 'Redstone 1', None, 'preview build'),
'14376': ( '10', None, 'Redstone 1', None, 'preview build'), '14376': ('10', None, 'Redstone 1', None, 'preview build'),
'14379': ( '10', None, 'Redstone 1', None, 'preview build'), '14379': ('10', None, 'Redstone 1', None, 'preview build'),
'14383': ( '10', None, 'Redstone 1', None, 'preview build'), '14383': ('10', None, 'Redstone 1', None, 'preview build'),
'14385': ( '10', None, 'Redstone 1', None, 'preview build'), '14385': ('10', None, 'Redstone 1', None, 'preview build'),
'14388': ( '10', None, 'Redstone 1', None, 'preview build'), '14388': ('10', None, 'Redstone 1', None, 'preview build'),
'14390': ( '10', None, 'Redstone 1', None, 'preview build'), '14390': ('10', None, 'Redstone 1', None, 'preview build'),
'14393': ( '10', 'v1607', 'Redstone 1', 'Anniversary Update', 'unsupported'), '14393': ('10', 'v1607', 'Redstone 1', 'Anniversary Update', 'unsupported'),
'14901': ( '10', None, 'Redstone 2', None, 'preview build'), '14901': ('10', None, 'Redstone 2', None, 'preview build'),
'14905': ( '10', None, 'Redstone 2', None, 'preview build'), '14905': ('10', None, 'Redstone 2', None, 'preview build'),
'14915': ( '10', None, 'Redstone 2', None, 'preview build'), '14915': ('10', None, 'Redstone 2', None, 'preview build'),
'14926': ( '10', None, 'Redstone 2', None, 'preview build'), '14926': ('10', None, 'Redstone 2', None, 'preview build'),
'14931': ( '10', None, 'Redstone 2', None, 'preview build'), '14931': ('10', None, 'Redstone 2', None, 'preview build'),
'14936': ( '10', None, 'Redstone 2', None, 'preview build'), '14936': ('10', None, 'Redstone 2', None, 'preview build'),
'14942': ( '10', None, 'Redstone 2', None, 'preview build'), '14942': ('10', None, 'Redstone 2', None, 'preview build'),
'14946': ( '10', None, 'Redstone 2', None, 'preview build'), '14946': ('10', None, 'Redstone 2', None, 'preview build'),
'14951': ( '10', None, 'Redstone 2', None, 'preview build'), '14951': ('10', None, 'Redstone 2', None, 'preview build'),
'14955': ( '10', None, 'Redstone 2', None, 'preview build'), '14955': ('10', None, 'Redstone 2', None, 'preview build'),
'14959': ( '10', None, 'Redstone 2', None, 'preview build'), '14959': ('10', None, 'Redstone 2', None, 'preview build'),
'14965': ( '10', None, 'Redstone 2', None, 'preview build'), '14965': ('10', None, 'Redstone 2', None, 'preview build'),
'14971': ( '10', None, 'Redstone 2', None, 'preview build'), '14971': ('10', None, 'Redstone 2', None, 'preview build'),
'14986': ( '10', None, 'Redstone 2', None, 'preview build'), '14986': ('10', None, 'Redstone 2', None, 'preview build'),
'15002': ( '10', None, 'Redstone 2', None, 'preview build'), '15002': ('10', None, 'Redstone 2', None, 'preview build'),
'15007': ( '10', None, 'Redstone 2', None, 'preview build'), '15007': ('10', None, 'Redstone 2', None, 'preview build'),
'15014': ( '10', None, 'Redstone 2', None, 'preview build'), '15014': ('10', None, 'Redstone 2', None, 'preview build'),
'15019': ( '10', None, 'Redstone 2', None, 'preview build'), '15019': ('10', None, 'Redstone 2', None, 'preview build'),
'15025': ( '10', None, 'Redstone 2', None, 'preview build'), '15025': ('10', None, 'Redstone 2', None, 'preview build'),
'15031': ( '10', None, 'Redstone 2', None, 'preview build'), '15031': ('10', None, 'Redstone 2', None, 'preview build'),
'15042': ( '10', None, 'Redstone 2', None, 'preview build'), '15042': ('10', None, 'Redstone 2', None, 'preview build'),
'15046': ( '10', None, 'Redstone 2', None, 'preview build'), '15046': ('10', None, 'Redstone 2', None, 'preview build'),
'15048': ( '10', None, 'Redstone 2', None, 'preview build'), '15048': ('10', None, 'Redstone 2', None, 'preview build'),
'15055': ( '10', None, 'Redstone 2', None, 'preview build'), '15055': ('10', None, 'Redstone 2', None, 'preview build'),
'15058': ( '10', None, 'Redstone 2', None, 'preview build'), '15058': ('10', None, 'Redstone 2', None, 'preview build'),
'15060': ( '10', None, 'Redstone 2', None, 'preview build'), '15060': ('10', None, 'Redstone 2', None, 'preview build'),
'15061': ( '10', None, 'Redstone 2', None, 'preview build'), '15061': ('10', None, 'Redstone 2', None, 'preview build'),
'15063': ( '10', 'v1703', 'Redstone 2', 'Creators Update', 'outdated'), '15063': ('10', 'v1703', 'Redstone 2', 'Creators Update', 'unsupported'),
'16170': ( '10', None, 'Redstone 3', None, 'preview build'), '16170': ('10', None, 'Redstone 3', None, 'preview build'),
'16176': ( '10', None, 'Redstone 3', None, 'preview build'), '16176': ('10', None, 'Redstone 3', None, 'preview build'),
'16179': ( '10', None, 'Redstone 3', None, 'preview build'), '16179': ('10', None, 'Redstone 3', None, 'preview build'),
'16184': ( '10', None, 'Redstone 3', None, 'preview build'), '16184': ('10', None, 'Redstone 3', None, 'preview build'),
'16188': ( '10', None, 'Redstone 3', None, 'preview build'), '16188': ('10', None, 'Redstone 3', None, 'preview build'),
'16193': ( '10', None, 'Redstone 3', None, 'preview build'), '16193': ('10', None, 'Redstone 3', None, 'preview build'),
'16199': ( '10', None, 'Redstone 3', None, 'preview build'), '16199': ('10', None, 'Redstone 3', None, 'preview build'),
'16212': ( '10', None, 'Redstone 3', None, 'preview build'), '16212': ('10', None, 'Redstone 3', None, 'preview build'),
'16215': ( '10', None, 'Redstone 3', None, 'preview build'), '16215': ('10', None, 'Redstone 3', None, 'preview build'),
'16226': ( '10', None, 'Redstone 3', None, 'preview build'), '16226': ('10', None, 'Redstone 3', None, 'preview build'),
'16232': ( '10', None, 'Redstone 3', None, 'preview build'), '16232': ('10', None, 'Redstone 3', None, 'preview build'),
'16237': ( '10', None, 'Redstone 3', None, 'preview build'), '16237': ('10', None, 'Redstone 3', None, 'preview build'),
'16241': ( '10', None, 'Redstone 3', None, 'preview build'), '16241': ('10', None, 'Redstone 3', None, 'preview build'),
'16251': ( '10', None, 'Redstone 3', None, 'preview build'), '16251': ('10', None, 'Redstone 3', None, 'preview build'),
'16257': ( '10', None, 'Redstone 3', None, 'preview build'), '16257': ('10', None, 'Redstone 3', None, 'preview build'),
'16273': ( '10', None, 'Redstone 3', None, 'preview build'), '16273': ('10', None, 'Redstone 3', None, 'preview build'),
'16275': ( '10', None, 'Redstone 3', None, 'preview build'), '16275': ('10', None, 'Redstone 3', None, 'preview build'),
'16278': ( '10', None, 'Redstone 3', None, 'preview build'), '16278': ('10', None, 'Redstone 3', None, 'preview build'),
'16281': ( '10', None, 'Redstone 3', None, 'preview build'), '16281': ('10', None, 'Redstone 3', None, 'preview build'),
'16288': ( '10', None, 'Redstone 3', None, 'preview build'), '16288': ('10', None, 'Redstone 3', None, 'preview build'),
'16291': ( '10', None, 'Redstone 3', None, 'preview build'), '16291': ('10', None, 'Redstone 3', None, 'preview build'),
'16294': ( '10', None, 'Redstone 3', None, 'preview build'), '16294': ('10', None, 'Redstone 3', None, 'preview build'),
'16296': ( '10', None, 'Redstone 3', None, 'preview build'), '16296': ('10', None, 'Redstone 3', None, 'preview build'),
'16299': ( '10', 'v1709', 'Redstone 3', 'Fall Creators Update', 'outdated'), '16299': ('10', 'v1709', 'Redstone 3', 'Fall Creators Update', 'outdated'),
'16353': ( '10', None, 'Redstone 4', None, 'preview build'), '16353': ('10', None, 'Redstone 4', None, 'preview build'),
'16362': ( '10', None, 'Redstone 4', None, 'preview build'), '16362': ('10', None, 'Redstone 4', None, 'preview build'),
'17004': ( '10', None, 'Redstone 4', None, 'preview build'), '17004': ('10', None, 'Redstone 4', None, 'preview build'),
'17017': ( '10', None, 'Redstone 4', None, 'preview build'), '17017': ('10', None, 'Redstone 4', None, 'preview build'),
'17025': ( '10', None, 'Redstone 4', None, 'preview build'), '17025': ('10', None, 'Redstone 4', None, 'preview build'),
'17035': ( '10', None, 'Redstone 4', None, 'preview build'), '17035': ('10', None, 'Redstone 4', None, 'preview build'),
'17040': ( '10', None, 'Redstone 4', None, 'preview build'), '17040': ('10', None, 'Redstone 4', None, 'preview build'),
'17046': ( '10', None, 'Redstone 4', None, 'preview build'), '17046': ('10', None, 'Redstone 4', None, 'preview build'),
'17063': ( '10', None, 'Redstone 4', None, 'preview build'), '17063': ('10', None, 'Redstone 4', None, 'preview build'),
'17074': ( '10', None, 'Redstone 4', None, 'preview build'), '17074': ('10', None, 'Redstone 4', None, 'preview build'),
'17083': ( '10', None, 'Redstone 4', None, 'preview build'), '17083': ('10', None, 'Redstone 4', None, 'preview build'),
'17093': ( '10', None, 'Redstone 4', None, 'preview build'), '17093': ('10', None, 'Redstone 4', None, 'preview build'),
'17101': ( '10', None, 'Redstone 4', None, 'preview build'), '17101': ('10', None, 'Redstone 4', None, 'preview build'),
'17107': ( '10', None, 'Redstone 4', None, 'preview build'), '17107': ('10', None, 'Redstone 4', None, 'preview build'),
'17110': ( '10', None, 'Redstone 4', None, 'preview build'), '17110': ('10', None, 'Redstone 4', None, 'preview build'),
'17112': ( '10', None, 'Redstone 4', None, 'preview build'), '17112': ('10', None, 'Redstone 4', None, 'preview build'),
'17115': ( '10', None, 'Redstone 4', None, 'preview build'), '17115': ('10', None, 'Redstone 4', None, 'preview build'),
'17120': ( '10', None, 'Redstone 4', None, 'preview build'), '17120': ('10', None, 'Redstone 4', None, 'preview build'),
'17123': ( '10', None, 'Redstone 4', None, 'preview build'), '17123': ('10', None, 'Redstone 4', None, 'preview build'),
'17127': ( '10', None, 'Redstone 4', None, 'preview build'), '17127': ('10', None, 'Redstone 4', None, 'preview build'),
'17128': ( '10', None, 'Redstone 4', None, 'preview build'), '17128': ('10', None, 'Redstone 4', None, 'preview build'),
'17133': ( '10', None, 'Redstone 4', None, 'preview build'), '17133': ('10', None, 'Redstone 4', None, 'preview build'),
'17134': ( '10', 'v1803', 'Redstone 4', 'April 2018 Update', None), '17134': ('10', 'v1803', 'Redstone 4', 'April 2018 Update', 'outdated'),
'17604': ( '10', None, 'Redstone 5', None, 'preview build'), '17604': ('10', None, 'Redstone 5', None, 'preview build'),
'17618': ( '10', None, 'Redstone 5', None, 'preview build'), '17618': ('10', None, 'Redstone 5', None, 'preview build'),
'17623': ( '10', None, 'Redstone 5', None, 'preview build'), '17623': ('10', None, 'Redstone 5', None, 'preview build'),
'17627': ( '10', None, 'Redstone 5', None, 'preview build'), '17627': ('10', None, 'Redstone 5', None, 'preview build'),
'17634': ( '10', None, 'Redstone 5', None, 'preview build'), '17634': ('10', None, 'Redstone 5', None, 'preview build'),
'17639': ( '10', None, 'Redstone 5', None, 'preview build'), '17639': ('10', None, 'Redstone 5', None, 'preview build'),
'17643': ( '10', None, 'Redstone 5', None, 'preview build'), '17643': ('10', None, 'Redstone 5', None, 'preview build'),
'17650': ( '10', None, 'Redstone 5', None, 'preview build'), '17650': ('10', None, 'Redstone 5', None, 'preview build'),
'17655': ( '10', None, 'Redstone 5', None, 'preview build'), '17655': ('10', None, 'Redstone 5', None, 'preview build'),
'17661': ( '10', None, 'Redstone 5', None, 'preview build'), '17661': ('10', None, 'Redstone 5', None, 'preview build'),
'17666': ( '10', None, 'Redstone 5', None, 'preview build'), '17666': ('10', None, 'Redstone 5', None, 'preview build'),
'17677': ( '10', None, 'Redstone 5', None, 'preview build'), '17677': ('10', None, 'Redstone 5', None, 'preview build'),
'17682': ( '10', None, 'Redstone 5', None, 'preview build'), '17682': ('10', None, 'Redstone 5', None, 'preview build'),
'17686': ( '10', None, 'Redstone 5', None, 'preview build'), '17686': ('10', None, 'Redstone 5', None, 'preview build'),
'17692': ( '10', None, 'Redstone 5', None, 'preview build'), '17692': ('10', None, 'Redstone 5', None, 'preview build'),
'17704': ( '10', None, 'Redstone 5', None, 'preview build'), '17704': ('10', None, 'Redstone 5', None, 'preview build'),
'17711': ( '10', None, 'Redstone 5', None, 'preview build'), '17711': ('10', None, 'Redstone 5', None, 'preview build'),
'17713': ( '10', None, 'Redstone 5', None, 'preview build'), '17713': ('10', None, 'Redstone 5', None, 'preview build'),
'17723': ( '10', None, 'Redstone 5', None, 'preview build'), '17723': ('10', None, 'Redstone 5', None, 'preview build'),
'17728': ( '10', None, 'Redstone 5', None, 'preview build'), '17728': ('10', None, 'Redstone 5', None, 'preview build'),
'17730': ( '10', None, 'Redstone 5', None, 'preview build'), '17730': ('10', None, 'Redstone 5', None, 'preview build'),
'17733': ( '10', None, 'Redstone 5', None, 'preview build'), '17733': ('10', None, 'Redstone 5', None, 'preview build'),
'17735': ( '10', None, 'Redstone 5', None, 'preview build'), '17735': ('10', None, 'Redstone 5', None, 'preview build'),
'17738': ( '10', None, 'Redstone 5', None, 'preview build'), '17738': ('10', None, 'Redstone 5', None, 'preview build'),
'17741': ( '10', None, 'Redstone 5', None, 'preview build'), '17741': ('10', None, 'Redstone 5', None, 'preview build'),
'17744': ( '10', None, 'Redstone 5', None, 'preview build'), '17744': ('10', None, 'Redstone 5', None, 'preview build'),
'17746': ( '10', None, 'Redstone 5', None, 'preview build'), '17746': ('10', None, 'Redstone 5', None, 'preview build'),
'17751': ( '10', None, 'Redstone 5', None, 'preview build'), '17751': ('10', None, 'Redstone 5', None, 'preview build'),
'17754': ( '10', None, 'Redstone 5', None, 'preview build'), '17754': ('10', None, 'Redstone 5', None, 'preview build'),
'17755': ( '10', None, 'Redstone 5', None, 'preview build'), '17755': ('10', None, 'Redstone 5', None, 'preview build'),
'17758': ( '10', None, 'Redstone 5', None, 'preview build'), '17758': ('10', None, 'Redstone 5', None, 'preview build'),
'17760': ( '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'), '17763': ('10', 'v1809', 'Redstone 5', 'October 2018 Update', None),
'18204': ( '10', None, '19H1', None, 'preview build'), '18204': ('10', None, '19H1', None, 'preview build'),
'18214': ( '10', None, '19H1', None, 'preview build'), '18214': ('10', None, '19H1', None, 'preview build'),
'18219': ( '10', None, '19H1', None, 'preview build'), '18219': ('10', None, '19H1', None, 'preview build'),
'18234': ( '10', None, '19H1', None, 'preview build'), '18234': ('10', None, '19H1', None, 'preview build'),
'18237': ( '10', None, '19H1', None, 'preview build'), '18237': ('10', None, '19H1', None, 'preview build'),
'18242': ( '10', None, '19H1', None, 'preview build'), '18242': ('10', None, '19H1', None, 'preview build'),
'18247': ( '10', None, '19H1', None, 'preview build'), '18247': ('10', None, '19H1', None, 'preview build'),
'18252': ( '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__': 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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.repairs import * from functions.repairs import *
init_global_vars() init_global_vars()
os.system('title {}: SFC Tool'.format(KIT_NAME_FULL)) os.system('title {}: SFC Tool'.format(KIT_NAME_FULL))
set_log_file('SFC Tool.log') set_log_file('SFC Tool.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
stay_awake() stay_awake()
clear_screen() clear_screen()
print_info('{}: SFC Tool\n'.format(KIT_NAME_FULL)) print_info('{}: SFC Tool\n'.format(KIT_NAME_FULL))
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
}, },
'Warning': { 'Warning': {
'GenericRepair': 'Repaired', 'GenericRepair': 'Repaired',
}} }}
if ask('Run a SFC scan now?'): if ask('Run a SFC scan now?'):
try_and_print(message='SFC scan...', try_and_print(message='SFC scan...',
function=run_sfc_scan, other_results=other_results) function=run_sfc_scan, other_results=other_results)
else: else:
abort() abort()
# Done # Done
print_standard('\nDone.') print_standard('\nDone.')
pause('Press Enter to exit...') pause('Press Enter to exit...')
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() 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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.browsers import * from functions.browsers import *
from functions.diags import *
from functions.info import * from functions.info import *
from functions.product_keys import * from functions.product_keys import *
from functions.repairs import * from functions.repairs import *
from functions.sw_diags import *
init_global_vars() init_global_vars()
os.system('title {}: System Diagnostics Tool'.format(KIT_NAME_FULL)) os.system('title {}: System Diagnostics Tool'.format(KIT_NAME_FULL))
set_log_file('System Diagnostics.log') set_log_file('System Diagnostics.log')
# Static Variables # Static Variables
BLEACH_BIT_CLEANERS = { BLEACH_BIT_CLEANERS = {
'Applications': ( 'Applications': (
'adobe_reader.cache', 'adobe_reader.cache',
'adobe_reader.tmp', 'adobe_reader.tmp',
'amule.tmp', 'amule.tmp',
'flash.cache', 'flash.cache',
'gimp.tmp', 'gimp.tmp',
'hippo_opensim_viewer.cache', 'hippo_opensim_viewer.cache',
'java.cache', 'java.cache',
'libreoffice.cache', 'libreoffice.cache',
'liferea.cache', 'liferea.cache',
'miro.cache', 'miro.cache',
'openofficeorg.cache', 'openofficeorg.cache',
'pidgin.cache', 'pidgin.cache',
'secondlife_viewer.Cache', 'secondlife_viewer.Cache',
'thunderbird.cache', 'thunderbird.cache',
'vuze.backup_files', 'vuze.backup_files',
'vuze.cache', 'vuze.cache',
'vuze.tmp', 'vuze.tmp',
'yahoo_messenger.cache', 'yahoo_messenger.cache',
), ),
'Browsers': ( 'Browsers': (
'chromium.cache', 'chromium.cache',
'chromium.current_session', 'chromium.current_session',
'firefox.cache', 'firefox.cache',
'firefox.session_restore', 'firefox.session_restore',
'google_chrome.cache', 'google_chrome.cache',
'google_chrome.session', 'google_chrome.session',
'google_earth.temporary_files', 'google_earth.temporary_files',
'internet_explorer.temporary_files', 'internet_explorer.temporary_files',
'opera.cache', 'opera.cache',
'opera.current_session', 'opera.current_session',
'safari.cache', 'safari.cache',
'seamonkey.cache', 'seamonkey.cache',
), ),
'System': ( 'System': (
'system.clipboard', 'system.clipboard',
'system.tmp', 'system.tmp',
'winapp2_windows.jump_lists', 'winapp2_windows.jump_lists',
'winapp2_windows.ms_search', 'winapp2_windows.ms_search',
'windows_explorer.run', 'windows_explorer.run',
'windows_explorer.search_history', 'windows_explorer.search_history',
'windows_explorer.thumbnails', 'windows_explorer.thumbnails',
), ),
} }
if __name__ == '__main__': 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: try:
stay_awake() show_user_data_summary()
clear_screen() except Exception:
print_info('{}: System Diagnostics Tool\n'.format(KIT_NAME_FULL)) print_error(' Unknown error.')
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 # Done
print_info('Sanitizing Environment') print_standard('\nDone.')
try_and_print(message='Running RKill...', pause('Press Enter to exit...')
function=run_rkill, cs='Done', other_results=other_results) exit_script()
try_and_print(message='Running TDSSKiller...', except SystemExit as sys_exit:
function=run_tdsskiller, cs='Done', other_results=other_results) exit_script(sys_exit.code)
except:
major_exception()
# Re-run if earlier process was stopped. # vim: sts=2 sw=2 ts=2
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

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

View file

@ -4,142 +4,140 @@ import os
import sys import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.update import * from functions.update import *
init_global_vars() init_global_vars()
os.system('title {}: Kit Update Tool'.format(KIT_NAME_FULL)) os.system('title {}: Kit Update Tool'.format(KIT_NAME_FULL))
if __name__ == '__main__': if __name__ == '__main__':
try: try:
clear_screen() clear_screen()
print_info('{}: Kit Update Tool\n'.format(KIT_NAME_FULL)) print_info('{}: Kit Update Tool\n'.format(KIT_NAME_FULL))
other_results = { other_results = {
'Error': { 'Error': {
'CalledProcessError': 'Unknown Error', 'CalledProcessError': 'Unknown Error',
}} }}
## Prep ## ## Prep ##
update_sdio = ask('Update SDI Origin?') update_sdio = ask('Update SDI Origin?')
## Download ## ## Download ##
print_success('Downloading tools') print_success('Downloading tools')
# Data Recovery # Data Recovery
print_info(' Data Recovery') print_info(' Data Recovery')
try_and_print(message='TestDisk / PhotoRec...', function=update_testdisk, other_results=other_results, width=40) try_and_print(message='TestDisk / PhotoRec...', function=update_testdisk, other_results=other_results, width=40)
# Data Transfers # Data Transfers
print_info(' Data Transfers') print_info(' Data Transfers')
try_and_print(message='FastCopy...', function=update_fastcopy, other_results=other_results, width=40) 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='wimlib...', function=update_wimlib, other_results=other_results, width=40)
try_and_print(message='XYplorer...', function=update_xyplorer, other_results=other_results, width=40) try_and_print(message='XYplorer...', function=update_xyplorer, other_results=other_results, width=40)
# Diagnostics # Diagnostics
print_info(' Diagnostics') print_info(' Diagnostics')
try_and_print(message='AIDA64...', function=update_aida64, other_results=other_results, width=40) 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='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='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='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='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='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='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='NirCmd...', function=update_nircmd, other_results=other_results, width=40)
try_and_print(message='ProduKey...', function=update_produkey, other_results=other_results, width=40) try_and_print(message='ProduKey...', function=update_produkey, other_results=other_results, width=40)
# Drivers # Drivers
print_info(' 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 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='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) try_and_print(message='Samsing Magician...', function=update_samsung_magician, other_results=other_results, width=40)
if update_sdio: if update_sdio:
try_and_print(message='Snappy Driver Installer Origin...', function=update_sdi_origin, other_results=other_results, width=40) try_and_print(message='Snappy Driver Installer Origin...', function=update_sdi_origin, other_results=other_results, width=40)
# Installers # Installers
print_info(' 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='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='LibreOffice...', function=update_libreoffice, 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='Macs Fan Control...', function=update_macs_fan_control, 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='MS Office...', function=update_office, other_results=other_results, width=40)
update_all_ninite(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 # Misc
print_info(' Misc') print_info(' Misc')
try_and_print(message='Caffeine...', function=update_caffeine, other_results=other_results, width=40) 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='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='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='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='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='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='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='WizTree...', function=update_wiztree, other_results=other_results, width=40)
try_and_print(message='XMPlay...', function=update_xmplay, other_results=other_results, width=40) try_and_print(message='XMPlay...', function=update_xmplay, other_results=other_results, width=40)
# Repairs # Repairs
print_info(' Repairs') print_info(' Repairs')
try_and_print(message='AdwCleaner...', function=update_adwcleaner, other_results=other_results, width=40) 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='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='RKill...', function=update_rkill, other_results=other_results, width=40)
try_and_print(message='TDSS Killer...', function=update_tdsskiller, other_results=other_results, width=40) try_and_print(message='TDSS Killer...', function=update_tdsskiller, other_results=other_results, width=40)
# Uninstallers # Uninstallers
print_info(' Uninstallers') print_info(' Uninstallers')
try_and_print(message='IObit Uninstaller...', function=update_iobit_uninstaller, other_results=other_results, width=40) try_and_print(message='IObit Uninstaller...', function=update_iobit_uninstaller, other_results=other_results, width=40)
## Review ## ## Review ##
print_standard('Please review the results and download/extract any missing items to .cbin') print_standard('Please review the results and download/extract any missing items to .cbin')
pause('Press Enter to compress the .cbin items') pause('Press Enter to compress the .cbin items')
## Compress ## ## Compress ##
print_success('Compressing tools') print_success('Compressing tools')
print_info(' _Drivers') print_info(' _Drivers')
for item in os.scandir(r'{}\_Drivers'.format(global_vars['CBinDir'])): for item in os.scandir(r'{}\_Drivers'.format(global_vars['CBinDir'])):
if not re.search(r'^(_Drivers|.*7z)$', item.name, re.IGNORECASE): if not re.search(r'^(_Drivers|.*7z)$', item.name, re.IGNORECASE):
try_and_print( try_and_print(
message='{}...'.format(item.name), message='{}...'.format(item.name),
function=compress_and_remove_item, function=compress_and_remove_item,
other_results = other_results, other_results = other_results,
width=40, width=40,
item = item) item = item)
print_info(' .cbin') print_info(' .cbin')
for item in os.scandir(global_vars['CBinDir']): for item in os.scandir(global_vars['CBinDir']):
if not re.search(r'^(_Drivers|_include|.*7z)$', item.name, re.IGNORECASE): if not re.search(r'^(_Drivers|_include|.*7z)$', item.name, re.IGNORECASE):
try_and_print( try_and_print(
message='{}...'.format(item.name), message='{}...'.format(item.name),
function=compress_and_remove_item, function=compress_and_remove_item,
other_results = other_results, other_results = other_results,
width=40, width=40,
item = item) item = item)
## Search for network Office/QuickBooks installers & add to LAUNCHERS ## Generate Launchers
print_success('Scanning for network installers') print_success('Generating launchers')
scan_for_net_installers(OFFICE_SERVER, 'Office', min_year=2010) for section in sorted(LAUNCHERS.keys()):
scan_for_net_installers(QUICKBOOKS_SERVER, 'QuickBooks', min_year=2015) 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 # Rename "Copy WizardKit.cmd" (if necessary)
print_success('Generating launchers') source = r'{}\Scripts\Copy WizardKit.cmd'.format(global_vars['BinDir'])
for section in sorted(LAUNCHERS.keys()): dest = r'{}\Copy {}.cmd'.format(global_vars['BaseDir'], KIT_NAME_FULL)
print_info(' {}'.format(section)) if os.path.exists(source):
for name, options in sorted(LAUNCHERS[section].items()): try:
try_and_print(message=name, function=generate_launcher, shutil.move(source, dest)
section=section, name=name, options=options, except Exception:
other_results=other_results, width=40) print_error(' Failed to rename "{}.cmd" to "{}.cmd"'.format(
'Copy WizardKit', KIT_NAME_FULL))
# Rename "Copy WizardKit.cmd" (if necessary) # Done
source = r'{}\Scripts\Copy WizardKit.cmd'.format(global_vars['BinDir']) print_standard('\nDone.')
dest = r'{}\Copy {}.cmd'.format(global_vars['BaseDir'], KIT_NAME_FULL) pause("Press Enter to exit...")
if os.path.exists(source): exit_script()
try: except SystemExit as sys_exit:
shutil.move(source, dest) exit_script(sys_exit.code)
except Exception: except:
print_error(' Failed to rename "{}.cmd" to "{}.cmd"'.format( major_exception()
'Copy WizardKit', KIT_NAME_FULL))
# Done # vim: sts=2 sw=2 ts=2
print_standard('\nDone.')
pause("Press Enter to exit...")
exit_script()
except SystemExit:
pass
except:
major_exception()

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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.data import * from functions.data import *
from functions.repairs import * from functions.repairs import *
init_global_vars() 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') set_log_file('User Data Transfer.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
# Prep # Prep
stay_awake() stay_awake()
clear_screen() clear_screen()
print_info('{}: User Data Transfer Tool\n'.format(KIT_NAME_FULL)) print_info('{}: User Data Transfer Tool\n'.format(KIT_NAME_FULL))
# Get backup name prefix # Get backup name prefix
ticket_number = get_ticket_number() ticket_number = get_ticket_number()
if ENABLED_TICKET_NUMBERS: if ENABLED_TICKET_NUMBERS:
backup_prefix = ticket_number backup_prefix = ticket_number
else: else:
backup_prefix = get_simple_string(prompt='Enter backup name prefix') backup_prefix = get_simple_string(prompt='Enter backup name prefix')
backup_prefix = backup_prefix.replace(' ', '_') backup_prefix = backup_prefix.replace(' ', '_')
# Set destination # Set destination
folder_path = r'{}\Transfer'.format(KIT_NAME_SHORT) folder_path = r'{}\Transfer'.format(KIT_NAME_SHORT)
dest = select_destination(folder_path=folder_path, dest = select_destination(folder_path=folder_path,
prompt='Which disk are we transferring to?') prompt='Which disk are we transferring to?')
# Set source items # Set source items
source = select_source(backup_prefix) source = select_source(backup_prefix)
items = scan_source(source, dest) items = scan_source(source, dest)
# Transfer # Transfer
clear_screen() clear_screen()
print_info('Transfer Details:\n') print_info('Transfer Details:\n')
if ENABLED_TICKET_NUMBERS: if ENABLED_TICKET_NUMBERS:
show_data('Ticket:', ticket_number) show_data('Ticket:', ticket_number)
show_data('Source:', source.path) show_data('Source:', source.path)
show_data('Destination:', dest) show_data('Destination:', dest)
if (not ask('Proceed with transfer?')): if (not ask('Proceed with transfer?')):
umount_backup_shares() umount_backup_shares()
abort() abort()
print_info('Transferring Data') print_info('Transferring Data')
transfer_source(source, dest, items) transfer_source(source, dest, items)
try_and_print(message='Removing extra files...', try_and_print(message='Removing extra files...',
function=cleanup_transfer, cs='Done', dest_path=dest) function=cleanup_transfer, cs='Done', dest_path=dest)
umount_backup_shares() umount_backup_shares()
# Done # Done
try_and_print(message='Running KVRT...', try_and_print(message='Running KVRT...',
function=run_kvrt, cs='Started') function=run_kvrt, cs='Started')
print_standard('\nDone.') print_standard('\nDone.')
pause("Press Enter to exit...") pause("Press Enter to exit...")
exit_script() exit_script()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() 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 import sys
# Init # Init
os.chdir(os.path.dirname(os.path.realpath(__file__))) sys.path.append(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.getcwd())
from functions.winpe_menus import * from functions.winpe_menus import *
# Fix 7-Zip name # Fix 7-Zip name
TOOLS['SevenZip'].pop('64') TOOLS['SevenZip'].pop('64')
@ -14,9 +13,11 @@ set_title('{}: Root Menu'.format(KIT_NAME_FULL))
set_log_file('WinPE.log') set_log_file('WinPE.log')
if __name__ == '__main__': if __name__ == '__main__':
try: try:
menu_root() menu_root()
except SystemExit: except SystemExit as sys_exit:
pass exit_script(sys_exit.code)
except: except:
major_exception() 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 icon /EFI/boot/icons/wk_memtest.png
loader /EFI/memtest86/memtestx64.efi loader /EFI/memtest86/memtestx64.efi
} }
menuentry "Linux" { menuentry "Linux" {
icon /EFI/boot/icons/wk_arch.png icon /EFI/boot/icons/wk_arch.png
loader /arch/boot/x86_64/vmlinuz loader /arch/boot/x86_64/vmlinuz
@ -26,15 +27,32 @@ menuentry "Linux" {
initrd /arch/boot/amd_ucode.img initrd /arch/boot/amd_ucode.img
initrd /arch/boot/x86_64/archiso.img initrd /arch/boot/x86_64/archiso.img
options "archisobasedir=arch archisolabel=%ARCHISO_LABEL% copytoram loglevel=3" options "archisobasedir=arch archisolabel=%ARCHISO_LABEL% copytoram loglevel=3"
submenuentry "Linux (i3)" {
add_options "i3"
}
submenuentry "Linux (CLI)" { 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-WINPE#menuentry "WindowsPE" {
#UFD# icon /EFI/boot/icons/wk_win.png #UFD-WINPE# ostype windows
#UFD# loader /EFI/microsoft/bootx64.efi #UFD-WINPE# icon /EFI/boot/icons/wk_win.png
#UFD#} #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