mirror of
https://github.com/LSPosed/MagiskOnWSALocal.git
synced 2025-04-25 17:59:35 +00:00
Merge branch 'LSPosed:main' into main
This commit is contained in:
commit
142e4331c2
56 changed files with 1924 additions and 1304 deletions
.gitattributes.gitignoreREADME.md
.github
ISSUE_TEMPLATE
workflows
arm64
gapps
system/system/priv-app
bin
docs
installer
linker
scripts
build.shextractMagisk.pyextractWSA.pyfixGappsProp.pygenerateGappsLink.pygenerateKernelSULink.pygenerateMagiskLink.pygenerateWSALinks.pyinit.lsp.magisk.rcinstall_deps.shmagisk_debug.shpost-fs-data.shrequirements.txtrun.sh
wine
x64
gapps
system/system/priv-app
xml
3
.gitattributes
vendored
3
.gitattributes
vendored
|
@ -1,5 +1,8 @@
|
|||
*.py text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.exe binary
|
||||
*.apk binary
|
||||
*.so binary
|
||||
*.xml text eol=crlf
|
||||
*.bat text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
|
11
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
11
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -79,10 +79,13 @@ body:
|
|||
description: Please copy and paste the error or submit a screenshot. Without log, the issue will be closed. /请复制粘贴错误或提交截图。无日志提交会被关闭。
|
||||
value: |
|
||||
<details>
|
||||
<summary>Details</summary>
|
||||
|
||||
|
||||
|
||||
|
||||
[//]: <> (Don't modify above)
|
||||
|
||||
```
|
||||
# Replace this line with the log / 将此行用日志替换
|
||||
```
|
||||
[//]: <> (Don't modify below)
|
||||
</details>
|
||||
validations:
|
||||
required: true
|
||||
|
|
2
.github/workflows/issue_moderator.yml
vendored
2
.github/workflows/issue_moderator.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check issue
|
||||
uses: tachiyomiorg/issue-moderator-action@v1
|
||||
uses: tachiyomiorg/issue-moderator-action@v2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
auto-close-rules: |
|
||||
|
|
13
.github/workflows/lock-closed-issues.yml
vendored
Normal file
13
.github/workflows/lock-closed-issues.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
name: Lock closed issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: OSDKDev/lock-issues@v1
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
25
.github/workflows/lock.yml
vendored
Normal file
25
.github/workflows/lock.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
name: 'Lock Threads'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
pull_request:
|
||||
types: [closed]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: lock
|
||||
|
||||
jobs:
|
||||
action:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v4
|
||||
with:
|
||||
exclude-any-issue-labels: 'do-not-autoclose'
|
||||
exclude-any-pr-labels: 'do-not-autoclose'
|
||||
include-any-pr-labels: 'spam'
|
27
.github/workflows/ps2check.yml
vendored
Normal file
27
.github/workflows/ps2check.yml
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
name: PSScript checker
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.ps1'
|
||||
- '.github/workflows/ps2check.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.ps1'
|
||||
- '.github/workflows/ps2check.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name : Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run PSScriptAnalyzer
|
||||
uses: microsoft/psscriptanalyzer-action@v1.0
|
||||
with:
|
||||
path: .\installer
|
||||
recurse: true
|
||||
includeDefaultRules: true
|
||||
enableExit: true
|
25
.github/workflows/shellcheck.yml
vendored
Normal file
25
.github/workflows/shellcheck.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
name: Shell checker
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.sh'
|
||||
- '.github/workflows/shellcheck.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.sh'
|
||||
- '.github/workflows/shellcheck.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name : Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run ShellCheck
|
||||
id: check
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
with:
|
||||
scandir: './scripts'
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
|||
download
|
||||
output
|
||||
python3-env
|
||||
token
|
||||
|
|
135
README.md
135
README.md
|
@ -1,135 +0,0 @@
|
|||
# Magisk on WSA (with Google Apps)
|
||||
|
||||
:warning: For fork developers: Please don't build using GitHub Actions, as GitHub will count your forked GitHub Actions usage against this upstream repository, which may cause this upstream repository gets disabled by GitHub staff like [MagiskOnWSA](https://github.com/LSPosed/MagiskOnWSA) because of numerous forks building GitHub Actions, and counting the forks' Action usage against this upstream repository.
|
||||
|
||||
## Support for generating from these systems
|
||||
|
||||
- Linux (x86_64 or arm64)
|
||||
|
||||
The following dependencies are required: `setools lzip wine patchelf e2fsprogs aria2 python3 attr`
|
||||
|
||||
The following components need to be installed using `winetricks`: `msxml6`
|
||||
|
||||
The python3 library `requests` is used.
|
||||
|
||||
Python version ≥ 3.7.
|
||||
- Recommended Use
|
||||
- Ubuntu (You can use [WSL2](https://apps.microsoft.com/store/search?publisher=Canonical%20Group%20Limited))
|
||||
|
||||
Ready to use right out of the box.
|
||||
- Debian (You can use [WSL2](https://apps.microsoft.com/store/detail/debian/9MSVKQC78PK6))
|
||||
|
||||
Need to add `contrib` sources to the source list to install winetricks.
|
||||
|
||||
- OpenSUSE (You can use [WSL2](https://apps.microsoft.com/store/search?publisher=SUSE))
|
||||
|
||||
Ready to use right out of the box.
|
||||
|
||||
`run.sh` will handle all dependencies automatically.
|
||||
|
||||
No need to type any commands.
|
||||
- Other Distributions
|
||||
|
||||
Install the dependencies manually.
|
||||
|
||||
Use the command-line program `build.sh`.
|
||||
|
||||
## Features
|
||||
|
||||
- Integrate Magisk and GApps in a few clicks within minutes
|
||||
- Keep each build up to date
|
||||
- Support both ARM64 and x64
|
||||
- Support all OpenGApps variants except for aroma (aroma does not support x86_64, please use super instead)
|
||||
- Remove Amazon Appstore
|
||||
- Fix VPN dialog not showing (use our [VpnDialogs app](https://github.com/LSPosed/VpnDialogs))
|
||||
- Add device administration feature
|
||||
- Unattended installation
|
||||
- Automatically activates developers mode in Windows 11
|
||||
- Update to the new version while preserving data with a one-click script
|
||||
- Merged all language packs
|
||||
- Support managing start menu icons (manually installing [WSAHelper](https://github.com/LSPosed/WSAHelper/releases/latest) to use this feature)
|
||||
|
||||
## Text Guide
|
||||
|
||||
1. Star (if you like)
|
||||
1. Clone the repo to local
|
||||
- Run `build.sh --help` to get the usage if you want to use CLI.
|
||||
1. Run `scripts/run.sh`
|
||||
1. Select the WSA version and its architecture (mostly x64)
|
||||
1. Select the version of Magisk
|
||||
1. Choose which brand of GApps you want to install
|
||||
- OpenGApps
|
||||
|
||||
Select the [OpenGApps variant](https://github.com/opengapps/opengapps/wiki#variants) you like.
|
||||
- MindtheGapps
|
||||
|
||||
There is no other variant we can choose.
|
||||
1. Select the root solution (none means no root)
|
||||
1. If you are running the script for the first time, it will take some time to complete. After the script completes, two new folders named `output` and `download` will be generated in the `MagiskOnWSALocal` folder. Go to the `output` folder. While running the `./run.sh` script in the step 3, if you selected `Yes` for `Do you want to compress the output?` then in `output` folder you will see a compressed file called `WSA-with-magisk-stable-MindTheGapps_2207.40000.8.0_x64_Release-Nightly`or else there will be folder with the `WSA-with-magisk-stable-MindTheGapps_2207.40000.8.0_x64_Release-Nightly`. If there is a folder open it and skip to step 10. NOTE: The name of compressed file or the folder generated in the `output` folder may be different for you. It will be dependent on the choices made when executing `./run.sh`
|
||||
1. Extract the compressed file and open the folder created after the extraction of the file.
|
||||
1. Here look for file `Run.bat` and run it.
|
||||
- If you previously have a MagiskOnWSA installation, it will automatically uninstall the previous one while **preserving all user data** and install the new one, so don't worry about your data.
|
||||
- If you have an official WSA installation, you should uninstall it first. (In case you want to preserve your data, you can backup `%LOCALAPPDATA%\Packages\MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe\LocalCache\userdata.vhdx` before uninstallation and restore it after installation.) (If you want to restore the icons to the start menu, please install and use [WSAHelper](https://github.com/LSPosed/WSAHelper/releases/latest).)
|
||||
- If the popup windows disappear **without asking administrative permission** and WSA is not installed successfully, you should manually run `Install.ps1` as administrator:
|
||||
1. Press `Win+x` and select `Windows Terminal (Admin)`
|
||||
2. Input `cd "{X:\path\to\your\extracted\folder}"` and press `enter`, and remember to replace `{X:\path\to\your\extracted\folder}` including the `{}`, for example `cd "D:\wsa"`
|
||||
3. Input `PowerShell.exe -ExecutionPolicy Bypass -File .\Install.ps1` and press `enter`
|
||||
4. The script will run and WSA will be installed
|
||||
5. If this workaround does not work, your PC is not supported for WSA
|
||||
1. Magisk/Play store will be launched. Enjoy by installing LSPosed-zygisk with zygisk enabled or Riru and LSPosed-riru
|
||||
|
||||
## FAQ
|
||||
|
||||
- Can I delete the installed folder?
|
||||
|
||||
No.
|
||||
- How can I update WSA to a new version?
|
||||
|
||||
Delete the `download` folder
|
||||
Rerun the script, replace the content of your previous installation and rerun `Install.ps1`. Don't worry, your data will be preserved.
|
||||
- How can I get the logcat from WSA?
|
||||
|
||||
`%LOCALAPPDATA%\Packages\MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe\LocalState\diagnostics\logcat`
|
||||
- How can I update Magisk to a new version?
|
||||
|
||||
Do the same as updating WSA
|
||||
- How to pass safetynet?
|
||||
|
||||
Like all the other emulators, no way.
|
||||
- Virtualization is not enabled?
|
||||
|
||||
`Install.ps1` helps you enable it if not enabled. After rebooting, rerun `Install.ps1` to install WSA. If it's still not working, you have to enable virtualization in BIOS. That's a long story so ask Google for help.
|
||||
- How to remount the system as read-write?
|
||||
|
||||
No way in WSA since it's mounted as read-only by Hyper-V. You can modify the system by making a Magisk module. Or directly modify the system.img. Ask Google for help.
|
||||
- I cannot `adb connect localhost:58526`
|
||||
|
||||
Make sure developer mode is enabled. If the issue persists, check the IP address of WSA on the setting page and try `adb connect ip:5555`.
|
||||
- Magisk online module list is empty?
|
||||
|
||||
Magisk actively removes the online module repository. You can install the module locally or by `adb push module.zip /data/local/tmp` and `adb shell su -c magisk --install-module /data/local/tmp/module.zip`.
|
||||
- Can I use Magisk 23.0 stable or a lower version?
|
||||
|
||||
No. Magisk has bugs preventing itself from running on WSA. Magisk 24+ has fixed them. So you must use Magisk 24 or higher version.
|
||||
- How can I get rid of Magisk?
|
||||
|
||||
Choose `none` as the root solution.
|
||||
- How to install custom GApps?
|
||||
|
||||
[Tutorial](./Custom-GApps.md)
|
||||
- Where can I download MindtheGapps?
|
||||
|
||||
You can download from here [MindtheGapps](https://androidfilehost.com/?w=files&flid=322935) ([mirror](http://downloads.codefi.re/jdcteam/javelinanddart/gapps))
|
||||
|
||||
Note that there is no x86_64 pre-build, so you need to build it by yourself ([Repository](https://gitlab.com/MindTheGapps/vendor_gapps)).
|
||||
- Can I switch OpenGApps to MindTheGapps and keep user data in a previous build?
|
||||
|
||||
No. You should wipe data after changing the GApps brand. Otherwise, you will find that the installed GApps are not recognized.
|
||||
|
||||
## Credits
|
||||
|
||||
- [StoreLib](https://github.com/StoreDev/StoreLib): API for downloading WSA
|
||||
- [Magisk](https://github.com/topjohnwu/Magisk): The most famous root solution on Android
|
||||
- [The Open GApps Project](https://opengapps.org): One of the most famous Google Apps packages solution
|
||||
- [WSA-Kernel-SU](https://github.com/LSPosed/WSA-Kernel-SU) and [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/): The kernel `su` for debugging Magisk Integration
|
||||
- [WSAGAScript](https://github.com/ADeltaX/WSAGAScript): The first GApps integration script for WSA
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/arm64/lspinit
Normal file
BIN
bin/arm64/lspinit
Normal file
Binary file not shown.
BIN
bin/arm64/makepri.exe
Normal file
BIN
bin/arm64/makepri.exe
Normal file
Binary file not shown.
BIN
bin/x64/lspinit
Normal file
BIN
bin/x64/lspinit
Normal file
Binary file not shown.
BIN
bin/x64/makepri.exe
Normal file
BIN
bin/x64/makepri.exe
Normal file
Binary file not shown.
19
docs/KernelSU.md
Normal file
19
docs/KernelSU.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Install KernelSU
|
||||
|
||||
## Install Manager
|
||||
|
||||
1. Download KernelSU Manager from [](https://github.com/tiann/KernelSU/actions/workflows/build-manager.yml?query=event%3Apush+is%3Acompleted+branch%3Amain) (Download the artifact named `manager`).
|
||||
|
||||
1. Unzip the downloaded zip package and get the manager apk named `KernelSU_vx.x.x-xx-.....apk`.
|
||||
|
||||
1. Use the command `adb install <apkname>.apk` to install the manager.
|
||||
|
||||
## Install Kernel
|
||||
|
||||
1. Download pre-build kernel from [](https://github.com/tiann/KernelSU/actions/workflows/build-kernel-wsa.yml?query=branch%3Amain+event%3Apush+is%3Acompleted) (Remember to download the same architecture).
|
||||
|
||||
1. Unzip the downloaded zip package and get the kernel file named `bzImage`.
|
||||
|
||||
1. Replace the kernel in the folder named `Tools` in the WSA directory with `bzImage`.
|
||||
|
||||
1. Restart WSA and then enjoy.
|
181
docs/README.md
Normal file
181
docs/README.md
Normal file
|
@ -0,0 +1,181 @@
|
|||
# Magisk on WSA (with Google Apps)
|
||||
|
||||
:warning: Magisk on WSA will no longer be available after March 5, 2025. [Learn more](https://learn.microsoft.com/en-us/windows/android/wsa/).
|
||||
|
||||
:warning: For fork developers: Please don't build using GitHub Actions, as GitHub will count your forked GitHub Actions usage against this upstream repository, which may cause this upstream repository gets disabled by GitHub staff like [MagiskOnWSA](https://github.com/LSPosed/MagiskOnWSA) because of numerous forks building GitHub Actions, and counting the forks' Action usage against this upstream repository.
|
||||
|
||||
## Support for generating from these systems
|
||||
|
||||
- Linux (x86_64 or arm64)
|
||||
|
||||
The following dependencies are required:
|
||||
|
||||
| DistrOS | | | | | |
|
||||
|:-------------------:|----------------------------|------------|--------------------|---------------|---------------|
|
||||
| Debian | `python3 aria2 unzip sudo` | `whiptail` | `python3-venv` | `python3-pip` | `p7zip-full` |
|
||||
| openSUSE Tumbleweed | Same as above | `dialog` | `python3-venvctrl` | Same as above | Same as above |
|
||||
| Arch | Same as Debian | `libnewt` | Same as Debian | `python-pip` | `p7zip` |
|
||||
|
||||
The python3 library `requests` is used.
|
||||
|
||||
Python version ≥ **3.7.2**.
|
||||
|
||||
- Recommended use
|
||||
|
||||
- Ubuntu (You can use [WSL2](https://apps.microsoft.com/store/search?publisher=Canonical%20Group%20Limited))
|
||||
|
||||
Ready to use right out of the box.
|
||||
|
||||
- Debian (You can use [WSL2](https://apps.microsoft.com/store/detail/debian/9MSVKQC78PK6))
|
||||
|
||||
Ready to use right out of the box.
|
||||
|
||||
- openSUSE Tumbleweed (You can use [WSL2](https://apps.microsoft.com/store/detail/opensuse-tumbleweed/9MSSK2ZXXN11))
|
||||
|
||||
Ready to use right out of the box.
|
||||
|
||||
`run.sh` will handle all dependencies automatically.
|
||||
|
||||
No need to type any commands.
|
||||
|
||||
## Features
|
||||
|
||||
- Integrate Magisk and GApps in a few clicks within minutes
|
||||
- Keep each build up to date
|
||||
- Support both ARM64 and x64
|
||||
- Support MindTheGapps
|
||||
- Remove Amazon Appstore
|
||||
- Fix VPN dialog not showing (use our [VpnDialogs app](https://github.com/LSPosed/VpnDialogs))
|
||||
- Add device administration feature
|
||||
- Unattended installation
|
||||
- Automatically activates developers mode in Windows 11
|
||||
- Update to the new version while preserving data with a one-click script
|
||||
- Merged all language packs
|
||||
|
||||
## Text Guide
|
||||
|
||||
1. Star (if you like).
|
||||
2. Clone the repo to local:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/LSPosed/MagiskOnWSALocal.git --depth 1
|
||||
```
|
||||
|
||||
3. Run `cd MagiskOnWSALocal`.
|
||||
4. Run `./scripts/run.sh`.
|
||||
5. Select the WSA version and its architecture (mostly x64).
|
||||
6. Select the version of Magisk.
|
||||
7. Choose which brand of GApps you want to install:
|
||||
- MindTheGapps
|
||||
|
||||
There is no other variant we can choose.
|
||||
8. Select the root solution (none means no root).
|
||||
9. If you are running the script for the first time, it will take some time to complete. After the script completes, two new folders named `output` and `download` will be generated in the `MagiskOnWSALocal` folder. Go to the `output` folder. While running the `./run.sh` script in the step 3, if you selected `Yes` for `Do you want to compress the output?` then in `output` folder you will see a compressed file called `WSA-with-magisk-stable-MindTheGapps_2207.40000.8.0_x64_Release-Nightly`or else there will be folder with the `WSA-with-magisk-stable-MindTheGapps_2207.40000.8.0_x64_Release-Nightly`. If there is a folder open it and skip to step 10. NOTE: The name of compressed file or the folder generated in the `output` folder may be different for you. It will be dependent on the choices made when executing `./run.sh`.
|
||||
10. Extract the compressed file and open the folder created after the extraction of the file.
|
||||
11. Here look for file `Run.bat` and run it.
|
||||
- If you previously have a MagiskOnWSA installation, it will automatically uninstall the previous one while **preserving all user data** and install the new one, so don't worry about your data.
|
||||
- If you have an official WSA installation, you should uninstall it first. (In case you want to preserve your data, you can backup `%LOCALAPPDATA%\Packages\MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe\LocalCache\userdata.vhdx` before uninstallation and restore it after installation.)
|
||||
- If the popup windows disappear **without asking administrative permission** and WSA is not installed successfully, you should manually run `Install.ps1` as Administrator:
|
||||
1. Press `Win+x` and select `Windows Terminal (Admin)`.
|
||||
2. Input `cd "{X:\path\to\your\extracted\folder}"` and press `enter`, and remember to replace `{X:\path\to\your\extracted\folder}` including the `{}`, for example `cd "D:\wsa"`
|
||||
3. Input `PowerShell.exe -ExecutionPolicy Bypass -File .\Install.ps1` and press `Enter`.
|
||||
4. The script will run and WSA will be installed.
|
||||
5. If this workaround does not work, your PC is not supported for WSA.
|
||||
12. Magisk/Play Store will be launched. Enjoy by installing LSPosed-Zygisk with Zygisk enabled or Riru and LSPosed-Riru.
|
||||
|
||||
---
|
||||
|
||||
## FAQ
|
||||
|
||||
<details open>
|
||||
|
||||
- Can I delete the installed folder?
|
||||
|
||||
No.
|
||||
|
||||
- How can I update WSA to a newer version?
|
||||
|
||||
1. Update build scripts:
|
||||
|
||||
```bash
|
||||
git pull
|
||||
```
|
||||
|
||||
For more usage of git, referred to <https://git-scm.com/book>
|
||||
|
||||
2. Rerun the script, replace the content of your previous installation and rerun `Install.ps1`. Don't worry, your data will be preserved.
|
||||
|
||||
- How can I get the logcat from WSA?
|
||||
|
||||
`%LOCALAPPDATA%\Packages\MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe\LocalState\diagnostics\logcat`
|
||||
|
||||
- How can I update Magisk to a newer version?
|
||||
|
||||
Do the same as updating WSA.
|
||||
|
||||
- How to pass Play Integrity (formerly known as SafetyNet)?
|
||||
|
||||
Like all the other emulators, no way.
|
||||
|
||||
- Virtualization is not enabled?
|
||||
|
||||
`Install.ps1` helps you enable it if not enabled. After rebooting, rerun `Install.ps1` to install WSA. If it's still not working, you have to enable virtualization in BIOS. That's a long story so ask Google for help.
|
||||
|
||||
- How to remount the system as read-write?
|
||||
|
||||
No way in WSA since it's mounted as read-only by Hyper-V. You can modify the system by making a Magisk module. Or directly modify the system.img. Ask Google for help.
|
||||
|
||||
- I cannot `adb connect localhost:58526`, what to do?
|
||||
|
||||
Make sure developer mode is enabled. If the issue persists, check the IP address of WSA on the setting page and try `adb connect ip:5555`.
|
||||
|
||||
- Why the Magisk online module is empty?
|
||||
|
||||
Magisk actively removes the online module repository. You can install the module locally or by `adb push module.zip /data/local/tmp` and `adb shell su -c magisk --install-module /data/local/tmp/module.zip`.
|
||||
|
||||
- Can I use Magisk v23.0 stable or a lower version?
|
||||
|
||||
No. Magisk has bugs preventing itself from running on WSA. Magisk v24+ has fixed them. So you must use Magisk v24 or later.
|
||||
|
||||
- How can I get rid of Magisk?
|
||||
|
||||
Choose `none` as the root solution.
|
||||
|
||||
- How to install custom GApps?
|
||||
|
||||
[Tutorial](Custom-GApps.md)
|
||||
|
||||
- Where can I download MindTheGapps?
|
||||
|
||||
You can download from here [MindTheGapps](https://androidfilehost.com/?w=files&flid=322935) ([mirror](http://downloads.codefi.re/jdcteam/javelinanddart/gapps)).
|
||||
|
||||
Note that there is no x86_64 pre-build, so you need to build it by yourself ([Repository](https://gitlab.com/MindTheGapps/vendor_gapps)).
|
||||
|
||||
Or you can download the built package for 12.1 and 13 for x86_64 from [this page](https://sourceforge.net/projects/wsa-mtg/files/x86_64/).
|
||||
|
||||
- Is it possible to migrate data from a lower version like 2305 to a newer version?
|
||||
|
||||
This is certainly available, Microsoft's change of read-only partition from 2305's EROFS to read-only EXT4 only affects the read-only system partition.
|
||||
|
||||
It has no effect on the user data partition. Check the logs if there is a failure to boot.
|
||||
|
||||
- How to install KernelSU?
|
||||
|
||||
[Tutorial](KernelSU.md)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Credits
|
||||
|
||||
- [StoreLib](https://github.com/StoreDev/StoreLib): API for downloading WSA
|
||||
- [Magisk](https://github.com/topjohnwu/Magisk): The most famous root solution on Android
|
||||
- ~~[The Open GApps Project](https://opengapps.org): One of the most famous Google Apps packages solution~~
|
||||
- [WSA-Kernel-SU](https://github.com/LSPosed/WSA-Kernel-SU) and [kernel-assisted-superuser](https://git.zx2c4.com/kernel-assisted-superuser/): The kernel `su` for debugging Magisk Integration
|
||||
- ~~[WSAGAScript](https://github.com/ADeltaX/WSAGAScript): The first GApps integration script for WSA~~
|
||||
- ~~[erofs-utils](https://github.com/sekaiacg/erofs-utils): Pre-build `erofs-utils` with erofsfuse enabled~~
|
||||
|
||||
_The repository is provided as a utility._
|
||||
|
||||
_Android is a trademark of Google LLC. Windows is a trademark of Microsoft Corporation._
|
177
installer/Install.ps1
Normal file
177
installer/Install.ps1
Normal file
|
@ -0,0 +1,177 @@
|
|||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
# MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
$Host.UI.RawUI.WindowTitle = "Installing MagiskOnWSA...."
|
||||
function Test-Administrator {
|
||||
[OutputType([bool])]
|
||||
param()
|
||||
process {
|
||||
[Security.Principal.WindowsPrincipal]$user = [Security.Principal.WindowsIdentity]::GetCurrent();
|
||||
return $user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator);
|
||||
}
|
||||
}
|
||||
|
||||
function Get-InstalledDependencyVersion {
|
||||
param (
|
||||
[string]$Name,
|
||||
[string]$ProcessorArchitecture
|
||||
)
|
||||
PROCESS {
|
||||
If ($null -Ne $ProcessorArchitecture) {
|
||||
return Get-AppxPackage -Name $Name | ForEach-Object { if ($_.Architecture -Eq $ProcessorArchitecture) { $_ } } | Sort-Object -Property Version | Select-Object -ExpandProperty Version -Last 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Test-CommandExist {
|
||||
Param ($Command)
|
||||
$OldPreference = $ErrorActionPreference
|
||||
$ErrorActionPreference = 'stop'
|
||||
try { if (Get-Command $Command) { RETURN $true } }
|
||||
Catch { RETURN $false }
|
||||
Finally { $ErrorActionPreference = $OldPreference }
|
||||
} #end function Test-CommandExist
|
||||
|
||||
Function Finish {
|
||||
Clear-Host
|
||||
Start-Process "wsa://com.topjohnwu.magisk"
|
||||
Start-Process "wsa://com.android.vending"
|
||||
}
|
||||
|
||||
If (Test-CommandExist pwsh.exe) {
|
||||
$pwsh = "pwsh.exe"
|
||||
}
|
||||
Else {
|
||||
$pwsh = "powershell.exe"
|
||||
}
|
||||
|
||||
If (-Not (Test-Administrator)) {
|
||||
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force
|
||||
$Proc = Start-Process -PassThru -Verb RunAs $pwsh -Args "-ExecutionPolicy Bypass -Command Set-Location '$PSScriptRoot'; &'$PSCommandPath' EVAL"
|
||||
If ($null -Ne $Proc) {
|
||||
$Proc.WaitForExit()
|
||||
}
|
||||
If ($null -Eq $Proc -Or $Proc.ExitCode -Ne 0) {
|
||||
Write-Warning "Failed to launch start as Administrator`r`nPress any key to exit"
|
||||
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
|
||||
}
|
||||
exit
|
||||
}
|
||||
ElseIf (($args.Count -Eq 1) -And ($args[0] -Eq "EVAL")) {
|
||||
Start-Process $pwsh -NoNewWindow -Args "-ExecutionPolicy Bypass -Command Set-Location '$PSScriptRoot'; &'$PSCommandPath'"
|
||||
exit
|
||||
}
|
||||
|
||||
$FileList = Get-Content -Path .\filelist.txt
|
||||
If (((Test-Path -Path $FileList) -Eq $false).Count) {
|
||||
Write-Error "Some files are missing in the folder. Please try to build again. Press any key to exit"
|
||||
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
exit 1
|
||||
}
|
||||
|
||||
If (((Test-Path -Path "MakePri.ps1") -And (Test-Path -Path "makepri.exe")) -Eq $true) {
|
||||
$ProcMakePri = Start-Process $pwsh -PassThru -NoNewWindow -Args "-ExecutionPolicy Bypass -File MakePri.ps1" -WorkingDirectory $PSScriptRoot
|
||||
$null = $ProcMakePri.Handle
|
||||
$ProcMakePri.WaitForExit()
|
||||
If ($ProcMakePri.ExitCode -Ne 0) {
|
||||
Write-Warning "Failed to merge resources, WSA Seetings will always be in English`r`nPress any key to continue"
|
||||
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
}
|
||||
$Host.UI.RawUI.WindowTitle = "Installing MagiskOnWSA...."
|
||||
}
|
||||
|
||||
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
|
||||
|
||||
# When using PowerShell which is installed with MSIX
|
||||
# Get-WindowsOptionalFeature and Enable-WindowsOptionalFeature will fail
|
||||
# See https://github.com/PowerShell/PowerShell/issues/13866
|
||||
if ($PSHOME.contains("8wekyb3d8bbwe")) {
|
||||
Import-Module DISM -UseWindowsPowerShell
|
||||
}
|
||||
|
||||
If ($(Get-WindowsOptionalFeature -Online -FeatureName 'VirtualMachinePlatform').State -Ne "Enabled") {
|
||||
Enable-WindowsOptionalFeature -Online -NoRestart -FeatureName 'VirtualMachinePlatform'
|
||||
Write-Warning "Need restart to enable virtual machine platform`r`nPress y to restart or press any key to exit"
|
||||
$Key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
If ("y" -Eq $Key.Character) {
|
||||
Restart-Computer -Confirm
|
||||
}
|
||||
Else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
[xml]$Xml = Get-Content ".\AppxManifest.xml";
|
||||
$Name = $Xml.Package.Identity.Name;
|
||||
Write-Output "Installing $Name version: $($Xml.Package.Identity.Version)"
|
||||
$ProcessorArchitecture = $Xml.Package.Identity.ProcessorArchitecture;
|
||||
$Dependencies = $Xml.Package.Dependencies.PackageDependency;
|
||||
$Dependencies | ForEach-Object {
|
||||
$InstalledVersion = Get-InstalledDependencyVersion -Name $_.Name -ProcessorArchitecture $ProcessorArchitecture;
|
||||
If ( $InstalledVersion -Lt $_.MinVersion ) {
|
||||
If ($env:WT_SESSION) {
|
||||
$env:WT_SESSION = $null
|
||||
Write-Output "Dependency should be installed but Windows Terminal is in use. Restarting to conhost.exe"
|
||||
Start-Process conhost.exe -Args "powershell.exe -ExecutionPolicy Bypass -Command Set-Location '$PSScriptRoot'; &'$PSCommandPath'"
|
||||
exit 1
|
||||
}
|
||||
Write-Output "Dependency package $($_.Name) $ProcessorArchitecture required minimum version: $($_.MinVersion). Installing...."
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Path "$($_.Name)_$ProcessorArchitecture.appx"
|
||||
}
|
||||
Else {
|
||||
Write-Output "Dependency package $($_.Name) $ProcessorArchitecture current version: $InstalledVersion. Nothing to do."
|
||||
}
|
||||
}
|
||||
|
||||
$Installed = $null
|
||||
$Installed = Get-AppxPackage -Name $Name
|
||||
|
||||
If (($null -Ne $Installed) -And (-Not ($Installed.IsDevelopmentMode))) {
|
||||
Write-Warning "There is already one installed WSA. Please uninstall it first.`r`nPress y to uninstall existing WSA or press any key to exit"
|
||||
$key = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
If ("y" -Eq $key.Character) {
|
||||
Clear-Host
|
||||
Remove-AppxPackage -Package $Installed.PackageFullName
|
||||
}
|
||||
Else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
If (Test-CommandExist WsaClient) {
|
||||
Write-Output "Shutting down WSA...."
|
||||
Start-Process WsaClient -Wait -Args "/shutdown"
|
||||
}
|
||||
Stop-Process -Name "WsaClient" -ErrorAction SilentlyContinue
|
||||
Write-Output "Installing MagiskOnWSA...."
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
|
||||
If ($?) {
|
||||
Finish
|
||||
}
|
||||
ElseIf ($null -Ne $Installed) {
|
||||
Write-Error "Failed to update.`r`nPress any key to uninstall existing installation while preserving user data.`r`nTake in mind that this will remove the Android apps' icon from the start menu.`r`nIf you want to cancel, close this window now."
|
||||
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
||||
Clear-Host
|
||||
Remove-AppxPackage -PreserveApplicationData -Package $Installed.PackageFullName
|
||||
Add-AppxPackage -ForceApplicationShutdown -ForceUpdateFromAnyVersion -Register .\AppxManifest.xml
|
||||
If ($?) {
|
||||
Finish
|
||||
}
|
||||
}
|
||||
Write-Output "All Done!`r`nPress any key to exit"
|
||||
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
|
70
installer/MakePri.ps1
Normal file
70
installer/MakePri.ps1
Normal file
|
@ -0,0 +1,70 @@
|
|||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
# MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2023 LSPosed Contributors
|
||||
#
|
||||
|
||||
$Host.UI.RawUI.WindowTitle = "Merging resources...."
|
||||
If ((Test-Path -Path "pri") -Eq $true -And (Test-Path -Path "xml") -Eq $true) {
|
||||
$AppxManifestFile = ".\AppxManifest.xml"
|
||||
Copy-Item .\resources.pri -Destination ".\pri\resources.pri" | Out-Null
|
||||
$ProcNew = Start-Process -PassThru makepri.exe -NoNewWindow -Args "new /pr .\pri /cf .\xml\priconfig.xml /of .\resources.pri /mn $AppxManifestFile /o"
|
||||
$null = $ProcNew.Handle
|
||||
$ProcNew.WaitForExit()
|
||||
If ($ProcNew.ExitCode -Ne 0) {
|
||||
Write-Warning "Failed to merge resources from pris`r`nTrying to dump pris to priinfo...."
|
||||
New-Item -Path "." -Name "priinfo" -ItemType "directory"
|
||||
Clear-Host
|
||||
$i = 0
|
||||
$PriItem = Get-Item ".\pri\*" -Include "*.pri"
|
||||
Write-Output "Dumping resources...."
|
||||
$Processes = ForEach ($Item in $PriItem) {
|
||||
Start-Process -PassThru -WindowStyle Hidden makepri.exe -Args "dump /if $($Item | Resolve-Path -Relative) /o /es .\pri\resources.pri /of .\priinfo\$($Item.Name).xml /dt detailed"
|
||||
$i = $i + 1
|
||||
$Completed = ($i / $PriItem.count) * 100
|
||||
Write-Progress -Activity "Dumping resources" -Status "Dumping $($Item.Name):" -PercentComplete $Completed
|
||||
}
|
||||
$Processes | Wait-Process
|
||||
Write-Progress -Activity "Dumping resources" -Status "Ready" -Completed
|
||||
Clear-Host
|
||||
Write-Output "Creating pri from dumps...."
|
||||
$ProcNewFromDump = Start-Process -PassThru -NoNewWindow makepri.exe -Args "new /pr .\priinfo /cf .\xml\priconfig.xml /of .\resources.pri /mn $AppxManifestFile /o"
|
||||
$null = $ProcNewFromDump.Handle
|
||||
$ProcNewFromDump.WaitForExit()
|
||||
Remove-Item 'priinfo' -Recurse
|
||||
If ($ProcNewFromDump.ExitCode -Ne 0) {
|
||||
Write-Error "Failed to create resources from priinfos"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
$ProjectXml = [xml](Get-Content $AppxManifestFile)
|
||||
$ProjectResources = $ProjectXml.Package.Resources;
|
||||
$(Get-Item .\xml\* -Exclude "priconfig.xml" -Include "*.xml") | ForEach-Object {
|
||||
$($([xml](Get-Content $_)).Package.Resources.Resource) | ForEach-Object {
|
||||
$ProjectResources.AppendChild($($ProjectXml.ImportNode($_, $true)))
|
||||
}
|
||||
}
|
||||
$ProjectXml.Save($AppxManifestFile)
|
||||
Remove-Item 'pri' -Recurse
|
||||
Set-Content -Path "filelist.txt" -Value (Get-Content -Path "filelist.txt" | Select-String -Pattern '^pri$' -NotMatch)
|
||||
Remove-Item 'xml' -Recurse
|
||||
Set-Content -Path "filelist.txt" -Value (Get-Content -Path "filelist.txt" | Select-String -Pattern '^xml$' -NotMatch)
|
||||
Remove-Item 'makepri.exe'
|
||||
Set-Content -Path "filelist.txt" -Value (Get-Content -Path "filelist.txt" | Select-String -Pattern 'makepri.exe' -NotMatch)
|
||||
Remove-Item $PSCommandPath -Force
|
||||
Set-Content -Path "filelist.txt" -Value (Get-Content -Path "filelist.txt" | Select-String -Pattern 'MakePri.ps1' -NotMatch)
|
||||
exit 0
|
||||
}
|
30
installer/Run.bat
Normal file
30
installer/Run.bat
Normal file
|
@ -0,0 +1,30 @@
|
|||
:: This file is part of MagiskOnWSALocal.
|
||||
::
|
||||
:: MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
:: it under the terms of the GNU Affero General Public License as
|
||||
:: published by the Free Software Foundation, either version 3 of the
|
||||
:: License, or (at your option) any later version.
|
||||
::
|
||||
:: MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
:: GNU Affero General Public License for more details.
|
||||
::
|
||||
:: You should have received a copy of the GNU Affero General Public License
|
||||
:: along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
::
|
||||
:: Copyright (C) 2023 LSPosed Contributors
|
||||
::
|
||||
|
||||
@echo off
|
||||
%~d0
|
||||
cd "%~dp0"
|
||||
if not exist Install.ps1 (
|
||||
echo "Install.ps1" is not found.
|
||||
echo Press any key to exit
|
||||
pause>nul
|
||||
exit 1
|
||||
) else (
|
||||
start powershell.exe -ExecutionPolicy Bypass -File .\Install.ps1
|
||||
exit
|
||||
)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1034
scripts/build.sh
1034
scripts/build.sh
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
|
@ -15,59 +15,69 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import os
|
||||
from typing import Any, OrderedDict
|
||||
|
||||
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, props: str = ...) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(props.splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 1)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||
self[__name] = __value
|
||||
|
||||
def __repr__(self):
|
||||
return '\n'.join(f'{item}={self[item]}' for item in self)
|
||||
|
||||
|
||||
is_x86_64 = platform.machine() in ("AMD64", "x86_64")
|
||||
host_abi = "x64" if is_x86_64 else "arm64"
|
||||
arch = sys.argv[1]
|
||||
magisk_zip = sys.argv[2]
|
||||
workdir = Path(sys.argv[3]) / "magisk"
|
||||
if not Path(workdir).is_dir():
|
||||
workdir.mkdir()
|
||||
workdir = Path(sys.argv[3])
|
||||
workdir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
abi_map = {"x64": ["x86_64", "x86"], "arm64": ["arm64-v8a", "armeabi-v7a"]}
|
||||
|
||||
|
||||
def extract_as(zip, name, as_name, dir):
|
||||
info = zip.getinfo(name)
|
||||
info.filename = as_name
|
||||
zip.extract(info, workdir / dir)
|
||||
|
||||
|
||||
with zipfile.ZipFile(magisk_zip) as zip:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagisk64.so", "magisk64", "magisk")
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][1] }/libmagisk32.so", "magisk32", "magisk")
|
||||
standalone_policy = False
|
||||
try:
|
||||
zip.getinfo(f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so")
|
||||
standalone_policy = True
|
||||
except:
|
||||
pass
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
|
||||
if standalone_policy:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskpolicy.so", "magiskpolicy", "magisk")
|
||||
props = Prop(zip.comment.decode().replace('\000', '\n'))
|
||||
namelist = zip.namelist()
|
||||
versionName = props.get("version")
|
||||
versionCode = props.get("versionCode")
|
||||
print(f"Magisk version: {versionName} ({versionCode})", flush=True)
|
||||
if 'WSA_WORK_ENV' in os.environ and Path(os.environ['WSA_WORK_ENV']).is_file():
|
||||
with open(os.environ['WSA_WORK_ENV'], 'r') as environ_file:
|
||||
env = Prop(environ_file.read())
|
||||
env.MAGISK_VERSION_NAME = versionName
|
||||
env.MAGISK_VERSION_CODE = versionCode
|
||||
with open(os.environ['WSA_WORK_ENV'], 'w') as environ_file:
|
||||
environ_file.write(str(env))
|
||||
if f"lib/{ abi_map[arch][0] }/libmagisk64.so" in namelist:
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagisk64.so", "magisk64", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[arch][1] }/libmagisk32.so", "magisk32", "magisk")
|
||||
else:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskpolicy", "magisk")
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libmagiskboot.so", "magiskboot", "magisk")
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[arch][0] }/libbusybox.so", "busybox", "magisk")
|
||||
if standalone_policy:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[host_abi][0] }/libmagiskpolicy.so", "magiskpolicy", ".")
|
||||
else:
|
||||
extract_as(
|
||||
zip, f"lib/{ abi_map[host_abi][0] }/libmagiskinit.so", "magiskpolicy", ".")
|
||||
extract_as(zip, f"assets/boot_patch.sh", "boot_patch.sh", "magisk")
|
||||
extract_as(zip, f"assets/util_functions.sh",
|
||||
"util_functions.sh", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagisk.so", "magisk", "magisk")
|
||||
if f"lib/{ abi_map[arch][0] }/libinit-ld.so" in namelist:
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libinit-ld.so", "init-ld", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[arch][0] }/libmagiskinit.so", "magiskinit", "magisk")
|
||||
extract_as(zip, f"lib/{ abi_map[host_abi][0] }/libmagiskboot.so", "magiskboot", "magisk")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
|
@ -15,58 +15,98 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
# Copyright (C) 2023 LSPosed Contributors
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
import warnings
|
||||
import zipfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from typing import Any, OrderedDict
|
||||
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
|
||||
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, props: str = ...) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(props.splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 1)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||
self[__name] = __value
|
||||
|
||||
def __repr__(self):
|
||||
return '\n'.join(f'{item}={self[item]}' for item in self)
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
arch = sys.argv[1]
|
||||
|
||||
zip_name = ""
|
||||
wsa_zip_path= Path(sys.argv[2]).resolve()
|
||||
workdir = Path(sys.argv[3]) / "wsa"
|
||||
wsa_zip_path = Path(sys.argv[2])
|
||||
rootdir = Path(sys.argv[3])
|
||||
env_file = Path(sys.argv[4])
|
||||
|
||||
workdir = rootdir / "wsa"
|
||||
archdir = Path(workdir / arch)
|
||||
pridir = workdir / archdir / 'pri'
|
||||
xmldir = workdir / archdir / 'xml'
|
||||
if not Path(rootdir).is_dir():
|
||||
rootdir.mkdir()
|
||||
|
||||
if Path(workdir).is_dir():
|
||||
shutil.rmtree(workdir)
|
||||
else:
|
||||
workdir.unlink(missing_ok=True)
|
||||
|
||||
if not Path(workdir).is_dir():
|
||||
workdir.mkdir()
|
||||
|
||||
if not Path(archdir).is_dir():
|
||||
archdir.mkdir()
|
||||
uid = os.getuid()
|
||||
workdir_rw = os.access(workdir, os.W_OK)
|
||||
|
||||
with zipfile.ZipFile(wsa_zip_path) as zip:
|
||||
for f in zip.filelist:
|
||||
if arch in f.filename.lower():
|
||||
filename_lower = f.filename.lower()
|
||||
if arch in filename_lower:
|
||||
zip_name = f.filename
|
||||
output_name = zip_name[11:-5]
|
||||
if not Path(workdir / zip_name).is_file():
|
||||
zip_path = workdir / zip_name
|
||||
print(f"unzipping to {workdir}", flush=True)
|
||||
zip.extract(f, workdir)
|
||||
print(f"unzipping {zip_name} to {workdir}", flush=True)
|
||||
zip_path = zip.extract(f, workdir)
|
||||
with zipfile.ZipFile(zip_path) as wsa_zip:
|
||||
stat = Path(zip_path).stat()
|
||||
print(f"unzipping from {zip_path}", flush=True)
|
||||
wsa_zip.extractall(archdir)
|
||||
ver_no = zip_name.split("_")
|
||||
long_ver = ver_no[1]
|
||||
ver = long_ver.split(".")
|
||||
main_ver = ver[0]
|
||||
with open(os.environ['WSA_WORK_ENV'], 'a') as g:
|
||||
g.write(f'WSA_VER={long_ver}\n')
|
||||
with open(os.environ['WSA_WORK_ENV'], 'a') as g:
|
||||
g.write(f'WSA_MAIN_VER={main_ver}\n')
|
||||
major_ver = ver[0]
|
||||
rel = ver_no[3].split(".")
|
||||
rell = str(rel[0])
|
||||
with open(os.environ['WSA_WORK_ENV'], 'a') as g:
|
||||
g.write(f'WSA_REL={rell}\n')
|
||||
if 'language' in f.filename.lower() or 'scale' in f.filename.lower():
|
||||
name = f.filename.split("-", 1)[1].split(".")[0]
|
||||
rel_long = str(rel[0])
|
||||
with open(env_file, 'r') as environ_file:
|
||||
env = Prop(environ_file.read())
|
||||
env.WSA_VER = long_ver
|
||||
env.WSA_MAJOR_VER = major_ver
|
||||
env.WSA_REL = rel_long
|
||||
with open(env_file, 'w') as environ_file:
|
||||
environ_file.write(str(env))
|
||||
if 'language' in filename_lower or 'scale' in filename_lower:
|
||||
name = f.filename.split("_")[2].split(".")[0]
|
||||
zip.extract(f, workdir)
|
||||
with zipfile.ZipFile(workdir / f.filename) as l:
|
||||
for g in l.filelist:
|
||||
if g.filename == 'resources.pri':
|
||||
g.filename = f'{name}.pri'
|
||||
l.extract(g, workdir / 'pri')
|
||||
g.filename = f'resources.{name}.pri'
|
||||
l.extract(g, pridir)
|
||||
elif g.filename == 'AppxManifest.xml':
|
||||
g.filename = f'{name}.xml'
|
||||
l.extract(g, workdir / 'xml')
|
||||
with zipfile.ZipFile(zip_path) as zip:
|
||||
if not Path(workdir / arch).is_dir():
|
||||
print(f"unzipping from {zip_path}", flush=True)
|
||||
zip.extractall(workdir / arch)
|
||||
g.filename = f'resources.{name}.xml'
|
||||
l.extract(g, xmldir)
|
||||
elif re.search(u'Images/.+\.png', g.filename):
|
||||
l.extract(g, archdir)
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
# MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
#
|
||||
|
||||
from __future__ import annotations
|
||||
from io import TextIOWrapper
|
||||
from typing import OrderedDict
|
||||
from pathlib import Path
|
||||
import sys
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, file: TextIOWrapper) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(file.read().splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 2)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '\n'.join([v if k.startswith('.') else f"{k}={v}" for k, v in self.items()])
|
||||
|
||||
def __iadd__(self, other: str) -> Prop:
|
||||
self[f".{len(self)}"] = other
|
||||
return self
|
||||
|
||||
|
||||
new_props = {
|
||||
("product", "brand"): "google",
|
||||
("product", "manufacturer"): "Google",
|
||||
("build", "product"): "redfin",
|
||||
("product", "name"): "redfin",
|
||||
("product", "device"): "redfin",
|
||||
("product", "model"): "Pixel 5",
|
||||
("build", "flavor"): "redfin-user"
|
||||
}
|
||||
|
||||
|
||||
def description(sec: str, p: Prop) -> str:
|
||||
return f"{p[f'ro.{sec}.build.flavor']} {p[f'ro.{sec}.build.version.release_or_codename']} {p[f'ro.{sec}.build.id']} {p[f'ro.{sec}.build.version.incremental']} {p[f'ro.{sec}.build.tags']}"
|
||||
|
||||
|
||||
def fingerprint(sec: str, p: Prop) -> str:
|
||||
return f"""{p[f"ro.product.{sec}.brand"]}/{p[f"ro.product.{sec}.name"]}/{p[f"ro.product.{sec}.device"]}:{p[f"ro.{sec}.build.version.release"]}/{p[f"ro.{sec}.build.id"]}/{p[f"ro.{sec}.build.version.incremental"]}:{p[f"ro.{sec}.build.type"]}/{p[f"ro.{sec}.build.tags"]}"""
|
||||
|
||||
|
||||
def fix_prop(sec, prop):
|
||||
if not Path(prop).is_file():
|
||||
return
|
||||
|
||||
print(f"fixing {prop}", flush=True)
|
||||
with open(prop, 'r') as f:
|
||||
p = Prop(f)
|
||||
|
||||
p += "# extra prop added by MagiskOnWSA"
|
||||
|
||||
for k, v in new_props.items():
|
||||
p[f"ro.{k[0]}.{k[1]}"] = v
|
||||
|
||||
if k[0] == "build":
|
||||
p[f"ro.{sec}.{k[0]}.{k[1]}"] = v
|
||||
elif k[0] == "product":
|
||||
p[f"ro.{k[0]}.{sec}.{k[1]}"] = v
|
||||
|
||||
p["ro.build.description"] = description(sec, p)
|
||||
p[f"ro.build.fingerprint"] = fingerprint(sec, p)
|
||||
p[f"ro.{sec}.build.description"] = description(sec, p)
|
||||
p[f"ro.{sec}.build.fingerprint"] = fingerprint(sec, p)
|
||||
p[f"ro.bootimage.build.fingerprint"] = fingerprint(sec, p)
|
||||
|
||||
with open(prop, 'w') as f:
|
||||
f.write(str(p))
|
||||
|
||||
|
||||
sys_path = sys.argv[1]
|
||||
for sec, prop in {"system": sys_path+"/system/build.prop", "product": sys_path+"/product/build.prop", "system_ext": sys_path+"/system_ext/build.prop", "vendor": sys_path+"/vendor/build.prop", "odm": sys_path+"/vendor/odm/etc/build.prop"}.items():
|
||||
fix_prop(sec, prop)
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
|
@ -15,9 +15,10 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
from datetime import datetime
|
||||
import sys
|
||||
|
||||
import requests
|
||||
|
@ -25,45 +26,54 @@ import json
|
|||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class BearerAuth(requests.auth.AuthBase):
|
||||
def __init__(self, token):
|
||||
self.token = token
|
||||
|
||||
def __call__(self, r):
|
||||
r.headers["authorization"] = "Bearer " + self.token
|
||||
return r
|
||||
|
||||
|
||||
github_auth = None
|
||||
if Path.cwd().joinpath('token').exists():
|
||||
with open(Path.cwd().joinpath('token'), 'r') as token_file:
|
||||
github_auth = BearerAuth(token_file.read())
|
||||
print("Using token file for authentication", flush=True)
|
||||
arch = sys.argv[1]
|
||||
brand = sys.argv[2]
|
||||
variant = sys.argv[3]
|
||||
download_dir = Path.cwd().parent / \
|
||||
"download" if sys.argv[4] == "" else Path(sys.argv[4]).resolve()
|
||||
tempScript = sys.argv[5]
|
||||
print(
|
||||
f"Generating {brand} download link: arch={arch} variant={variant}", flush=True)
|
||||
arg2 = sys.argv[2]
|
||||
download_dir = Path.cwd().parent / "download" if arg2 == "" else Path(arg2)
|
||||
tempScript = sys.argv[3]
|
||||
android_api = sys.argv[4]
|
||||
file_name = sys.argv[5]
|
||||
print(f"Generating GApps download link: arch={arch}", flush=True)
|
||||
abi_map = {"x64": "x86_64", "arm64": "arm64"}
|
||||
# TODO: keep it 11.0 since opengapps does not support 12+ yet
|
||||
# As soon as opengapps is available for 12+, we need to get the sdk/release from build.prop and
|
||||
# download the corresponding version
|
||||
release = "11.0"
|
||||
if brand == "OpenGApps":
|
||||
try:
|
||||
res = requests.get(f"https://api.opengapps.org/list")
|
||||
j = json.loads(res.content)
|
||||
link = {i["name"]: i for i in j["archs"][abi_map[arch]]
|
||||
["apis"][release]["variants"]}[variant]["zip"]
|
||||
DATE=j["archs"][abi_map[arch]]["date"]
|
||||
print(f"DATE={DATE}", flush=True)
|
||||
except Exception:
|
||||
print("Failed to fetch from OpenGApps API, fallbacking to SourceForge RSS...")
|
||||
res = requests.get(
|
||||
f'https://sourceforge.net/projects/opengapps/rss?path=/{abi_map[arch]}&limit=100')
|
||||
link = re.search(f'https://.*{abi_map[arch]}/.*{release}.*{variant}.*\.zip/download', res.text).group().replace(
|
||||
'.zip/download', '.zip').replace('sourceforge.net/projects/opengapps/files', 'downloads.sourceforge.net/project/opengapps')
|
||||
elif brand == "MindTheGapps":
|
||||
res = requests.get(
|
||||
f'https://sourceforge.net/projects/wsa-mtg/rss?path=/{abi_map[arch]}&limit=100')
|
||||
link = re.search(f'https://.*{abi_map[arch]}/.*\.zip/download', res.text).group().replace(
|
||||
'.zip/download', '.zip').replace('sourceforge.net/projects/wsa-mtg/files', 'downloads.sourceforge.net/project/wsa-mtg')
|
||||
|
||||
print(f"download link: {link}", flush=True)
|
||||
|
||||
with open(download_dir/tempScript, 'a') as f:
|
||||
f.writelines(f'{link}\n')
|
||||
f.writelines(f' dir={download_dir}\n')
|
||||
if brand == "OpenGApps":
|
||||
f.writelines(f' out={brand}-{arch}-{variant}.zip\n')
|
||||
elif brand == "MindTheGapps":
|
||||
f.writelines(f' out={brand}-{arch}.zip\n')
|
||||
android_api_map = {"30": "11.0", "32": "12.1", "33": "13.0"}
|
||||
release = android_api_map[android_api]
|
||||
res = requests.get(f"https://api.github.com/repos/LSPosed/WSA-Addon/releases/latest", auth=github_auth)
|
||||
json_data = json.loads(res.content)
|
||||
headers = res.headers
|
||||
x_ratelimit_remaining = headers["x-ratelimit-remaining"]
|
||||
if res.status_code == 200:
|
||||
download_files = {}
|
||||
assets = json_data["assets"]
|
||||
for asset in assets:
|
||||
if re.match(f'gapps.*{release}.*\.rc$', asset["name"]):
|
||||
download_files[asset["name"]] = asset["browser_download_url"]
|
||||
elif re.match(f'gapps.*{release}.*{abi_map[arch]}.*\.img$', asset["name"]):
|
||||
download_files[asset["name"]] = asset["browser_download_url"]
|
||||
with open(download_dir/tempScript, 'a') as f:
|
||||
for key, value in download_files.items():
|
||||
print(f"download link: {value}\npath: {download_dir / key}\n", flush=True)
|
||||
f.writelines(value + '\n')
|
||||
f.writelines(f' dir={download_dir}\n')
|
||||
f.writelines(f' out={key}\n')
|
||||
elif res.status_code == 403 and x_ratelimit_remaining == '0':
|
||||
message = json_data["message"]
|
||||
print(f"Github API Error: {message}", flush=True)
|
||||
ratelimit_reset = headers["x-ratelimit-reset"]
|
||||
ratelimit_reset = datetime.fromtimestamp(int(ratelimit_reset))
|
||||
print(
|
||||
f"The current rate limit window resets in {ratelimit_reset}", flush=True)
|
||||
exit(1)
|
||||
|
|
106
scripts/generateKernelSULink.py
Normal file
106
scripts/generateKernelSULink.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
# MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
from datetime import datetime
|
||||
import sys
|
||||
import os
|
||||
from typing import Any, OrderedDict
|
||||
|
||||
import requests
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from packaging import version
|
||||
|
||||
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, props: str = ...) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(props.splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 1)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||
self[__name] = __value
|
||||
|
||||
def __repr__(self):
|
||||
return '\n'.join(f'{item}={self[item]}' for item in self)
|
||||
|
||||
|
||||
arch = sys.argv[1]
|
||||
arg2 = sys.argv[2]
|
||||
download_dir = Path.cwd().parent / "download" if arg2 == "" else Path(arg2)
|
||||
tempScript = sys.argv[3]
|
||||
kernelVersion = sys.argv[4]
|
||||
file_name = sys.argv[5]
|
||||
abi_map = {"x64": "x86_64", "arm64": "arm64"}
|
||||
print(
|
||||
f"Generating KernelSU download link: arch={abi_map[arch]}, kernel version={kernelVersion}", flush=True)
|
||||
res = requests.get(
|
||||
f"https://api.github.com/repos/tiann/KernelSU/releases/latest")
|
||||
json_data = json.loads(res.content)
|
||||
headers = res.headers
|
||||
x_ratelimit_remaining = headers["x-ratelimit-remaining"]
|
||||
kernel_ver = 0
|
||||
if res.status_code == 200:
|
||||
link = ""
|
||||
assets = json_data["assets"]
|
||||
for asset in assets:
|
||||
asset_name = asset["name"]
|
||||
if re.match(f'kernel-WSA-{abi_map[arch]}-{kernelVersion}.*\.zip$', asset_name) and asset["content_type"] == "application/zip":
|
||||
tmp_kernel_ver = re.search(
|
||||
u'\d{1}.\d{1,}.\d{1,}.\d{1,}', asset_name.split("-")[3]).group()
|
||||
if (kernel_ver == 0):
|
||||
kernel_ver = tmp_kernel_ver
|
||||
elif version.parse(kernel_ver) < version.parse(tmp_kernel_ver):
|
||||
kernel_ver = tmp_kernel_ver
|
||||
print(f"Kernel version: {kernel_ver}", flush=True)
|
||||
for asset in assets:
|
||||
if re.match(f'kernel-WSA-{abi_map[arch]}-{kernel_ver}.*\.zip$', asset["name"]) and asset["content_type"] == "application/zip":
|
||||
link = asset["browser_download_url"]
|
||||
break
|
||||
if link == "":
|
||||
print(
|
||||
f"Error: No KernelSU release found for arch={abi_map[arch]}, kernel version={kernelVersion}", flush=True)
|
||||
exit(1)
|
||||
release_name = json_data["name"]
|
||||
with open(os.environ['WSA_WORK_ENV'], 'r') as environ_file:
|
||||
env = Prop(environ_file.read())
|
||||
env.KERNELSU_VER = release_name
|
||||
with open(os.environ['WSA_WORK_ENV'], 'w') as environ_file:
|
||||
environ_file.write(str(env))
|
||||
elif res.status_code == 403 and x_ratelimit_remaining == '0':
|
||||
message = json_data["message"]
|
||||
print(f"Github API Error: {message}", flush=True)
|
||||
ratelimit_reset = headers["x-ratelimit-reset"]
|
||||
ratelimit_reset = datetime.fromtimestamp(int(ratelimit_reset))
|
||||
print(
|
||||
f"The current rate limit window resets in {ratelimit_reset}", flush=True)
|
||||
exit(1)
|
||||
|
||||
print(f"download link: {link}", flush=True)
|
||||
|
||||
with open(download_dir/tempScript, 'a') as f:
|
||||
f.writelines(f'{link}\n')
|
||||
f.writelines(f' dir={download_dir}\n')
|
||||
f.writelines(f' out={file_name}\n')
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
|
@ -15,32 +15,76 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
# Copyright (C) 2023 LSPosed Contributors
|
||||
#
|
||||
|
||||
from datetime import datetime
|
||||
import re
|
||||
import sys
|
||||
|
||||
import json
|
||||
import requests
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class BearerAuth(requests.auth.AuthBase):
|
||||
def __init__(self, token):
|
||||
self.token = token
|
||||
|
||||
def __call__(self, r):
|
||||
r.headers["authorization"] = "Bearer " + self.token
|
||||
return r
|
||||
|
||||
|
||||
github_auth = None
|
||||
if Path.cwd().joinpath('token').exists():
|
||||
with open(Path.cwd().joinpath('token'), 'r') as token_file:
|
||||
github_auth = BearerAuth(token_file.read())
|
||||
print("Using token file for authentication", flush=True)
|
||||
|
||||
magisk_ver = sys.argv[1]
|
||||
download_dir = Path.cwd().parent / "download" if sys.argv[2] == "" else Path(sys.argv[2]).resolve()
|
||||
download_dir = Path.cwd().parent / \
|
||||
"download" if sys.argv[2] == "" else Path(sys.argv[2])
|
||||
tempScript = sys.argv[3]
|
||||
print(f"Generating Magisk download link: release type={magisk_ver}", flush=True)
|
||||
download_files = {}
|
||||
print(
|
||||
f"Generating Magisk download link: release type={magisk_ver}", flush=True)
|
||||
if not magisk_ver:
|
||||
magisk_ver = "stable"
|
||||
if magisk_ver == "stable" or magisk_ver == "beta" or magisk_ver == "canary" or magisk_ver == "debug":
|
||||
try:
|
||||
magisk_link = json.loads(requests.get(
|
||||
f"https://github.com/topjohnwu/magisk-files/raw/master/{magisk_ver}.json").content)['magisk']['link']
|
||||
download_files[f"magisk-{magisk_ver}.zip"] = magisk_link
|
||||
except Exception:
|
||||
print("Failed to fetch from GitHub API, fallbacking to jsdelivr...")
|
||||
magisk_link = json.loads(requests.get(
|
||||
f"https://fastly.jsdelivr.net/gh/topjohnwu/magisk-files@master/{magisk_ver}.json").content)['magisk']['link']
|
||||
print(f"download link: {magisk_link}", flush=True)
|
||||
download_files[f"magisk-{magisk_ver}.zip"] = magisk_link
|
||||
res = requests.get(
|
||||
f"https://api.github.com/repos/LSPosed/WSA-Addon/releases/latest", auth=github_auth)
|
||||
json_data = json.loads(res.content)
|
||||
headers = res.headers
|
||||
x_ratelimit_remaining = headers["x-ratelimit-remaining"]
|
||||
if res.status_code == 200:
|
||||
assets = json_data["assets"]
|
||||
for asset in assets:
|
||||
if re.match(f'cust.img$', asset["name"]):
|
||||
download_files[asset["name"]] = asset["browser_download_url"]
|
||||
break
|
||||
|
||||
elif res.status_code == 403 and x_ratelimit_remaining == '0':
|
||||
message = json_data["message"]
|
||||
print(f"Github API Error: {message}", flush=True)
|
||||
ratelimit_reset = headers["x-ratelimit-reset"]
|
||||
ratelimit_reset = datetime.fromtimestamp(int(ratelimit_reset))
|
||||
print(
|
||||
f"The current rate limit window resets in {ratelimit_reset}", flush=True)
|
||||
exit(1)
|
||||
with open(download_dir/tempScript, 'a') as f:
|
||||
f.writelines(f'{magisk_link}\n')
|
||||
f.writelines(f' dir={download_dir}\n')
|
||||
f.writelines(f' out=magisk-{magisk_ver}.zip\n')
|
||||
for key, value in download_files.items():
|
||||
print(
|
||||
f"download link: {value}\npath: {download_dir / key}\n", flush=True)
|
||||
f.writelines(value + '\n')
|
||||
f.writelines(f' dir={download_dir}\n')
|
||||
f.writelines(f' out={key}\n')
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
|
@ -15,100 +15,178 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
import html
|
||||
import logging
|
||||
import re
|
||||
import sys
|
||||
|
||||
import requests
|
||||
from xml.dom import minidom
|
||||
import html
|
||||
import warnings
|
||||
import re
|
||||
from pathlib import Path
|
||||
from threading import Thread
|
||||
from typing import Any, OrderedDict
|
||||
from xml.dom import minidom
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
from requests import Session
|
||||
from packaging import version
|
||||
|
||||
|
||||
class Prop(OrderedDict):
|
||||
def __init__(self, props: str = ...) -> None:
|
||||
super().__init__()
|
||||
for i, line in enumerate(props.splitlines(False)):
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 1)
|
||||
self[k] = v
|
||||
else:
|
||||
self[f".{i}"] = line
|
||||
|
||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||
self[__name] = __value
|
||||
|
||||
def __repr__(self):
|
||||
return '\n'.join(f'{item}={self[item]}' for item in self)
|
||||
|
||||
|
||||
logging.captureWarnings(True)
|
||||
arch = sys.argv[1]
|
||||
|
||||
release_name_map = {"retail": "Retail", "RP": "Release Preview",
|
||||
"WIS": "Insider Slow", "WIF": "Insider Fast"}
|
||||
release_type = sys.argv[2] if sys.argv[2] != "" else "Retail"
|
||||
release_name = release_name_map[release_type]
|
||||
download_dir = Path.cwd().parent / "download" if sys.argv[3] == "" else Path(sys.argv[3]).resolve()
|
||||
download_dir = Path.cwd().parent / \
|
||||
"download" if sys.argv[3] == "" else Path(sys.argv[3])
|
||||
ms_account_conf = download_dir/".ms_account"
|
||||
tempScript = sys.argv[4]
|
||||
skip_wsa_download = sys.argv[5] == "1" if len(sys.argv) >= 6 else False
|
||||
cat_id = '858014f3-3934-4abe-8078-4aa193e74ca8'
|
||||
print(f"Generating WSA download link: arch={arch} release_type={release_name}", flush=True)
|
||||
user = ''
|
||||
session = Session()
|
||||
session.verify = False
|
||||
if ms_account_conf.is_file():
|
||||
with open(ms_account_conf, "r") as f:
|
||||
conf = Prop(f.read())
|
||||
user = conf.get('user_code')
|
||||
print(
|
||||
f"Generating WSA download link: arch={arch} release_type={release_name}\n", flush=True)
|
||||
with open(Path.cwd().parent / ("xml/GetCookie.xml"), "r") as f:
|
||||
cookie_content = f.read()
|
||||
cookie_content = f.read().format(user)
|
||||
|
||||
out = requests.post(
|
||||
out = session.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
|
||||
data=cookie_content,
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'}
|
||||
)
|
||||
doc = minidom.parseString(out.text)
|
||||
cookie = doc.getElementsByTagName('EncryptedData')[0].firstChild.nodeValue
|
||||
|
||||
with open(Path.cwd().parent / "xml/WUIDRequest.xml", "r") as f:
|
||||
cat_id_content = f.read().format(cookie, cat_id, release_type)
|
||||
cat_id_content = f.read().format(user, cookie, cat_id, release_type)
|
||||
|
||||
out = requests.post(
|
||||
out = session.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx',
|
||||
data=cat_id_content,
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'}
|
||||
)
|
||||
|
||||
doc = minidom.parseString(html.unescape(out.text))
|
||||
|
||||
filenames = {}
|
||||
for node in doc.getElementsByTagName('Files'):
|
||||
filenames[node.parentNode.parentNode.getElementsByTagName(
|
||||
'ID')[0].firstChild.nodeValue] = f"{node.firstChild.attributes['InstallerSpecificIdentifier'].value}_{node.firstChild.attributes['FileName'].value}"
|
||||
pass
|
||||
for node in doc.getElementsByTagName('ExtendedUpdateInfo')[0].getElementsByTagName('Updates')[0].getElementsByTagName('Update'):
|
||||
node_xml = node.getElementsByTagName('Xml')[0]
|
||||
node_files = node_xml.getElementsByTagName('Files')
|
||||
if not node_files:
|
||||
continue
|
||||
else:
|
||||
for node_file in node_files[0].getElementsByTagName('File'):
|
||||
if node_file.hasAttribute('InstallerSpecificIdentifier') and node_file.hasAttribute('FileName'):
|
||||
filenames[node.getElementsByTagName('ID')[0].firstChild.nodeValue] = (f"{node_file.attributes['InstallerSpecificIdentifier'].value}_{node_file.attributes['FileName'].value}",
|
||||
node_xml.getElementsByTagName('ExtendedProperties')[0].attributes['PackageIdentityName'].value)
|
||||
|
||||
identities = []
|
||||
for node in doc.getElementsByTagName('SecuredFragment'):
|
||||
filename = filenames[node.parentNode.parentNode.parentNode.getElementsByTagName('ID')[
|
||||
0].firstChild.nodeValue]
|
||||
update_identity = node.parentNode.parentNode.firstChild
|
||||
identities += [(update_identity.attributes['UpdateID'].value,
|
||||
update_identity.attributes['RevisionNumber'].value, filename)]
|
||||
identities = {}
|
||||
for node in doc.getElementsByTagName('NewUpdates')[0].getElementsByTagName('UpdateInfo'):
|
||||
node_xml = node.getElementsByTagName('Xml')[0]
|
||||
if not node_xml.getElementsByTagName('SecuredFragment'):
|
||||
continue
|
||||
else:
|
||||
id = node.getElementsByTagName('ID')[0].firstChild.nodeValue
|
||||
update_identity = node_xml.getElementsByTagName('UpdateIdentity')[0]
|
||||
if id in filenames:
|
||||
fileinfo = filenames[id]
|
||||
if fileinfo[0] not in identities:
|
||||
identities[fileinfo[0]] = ([update_identity.attributes['UpdateID'].value,
|
||||
update_identity.attributes['RevisionNumber'].value], fileinfo[1])
|
||||
|
||||
with open(Path.cwd().parent / "xml/FE3FileUrl.xml", "r") as f:
|
||||
file_content = f.read()
|
||||
FE3_file_content = f.read()
|
||||
|
||||
if not download_dir.is_dir():
|
||||
download_dir.mkdir()
|
||||
|
||||
tmpdownlist = open(download_dir/tempScript, 'a')
|
||||
for i, v, f in identities:
|
||||
if re.match(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx", f):
|
||||
out_file_name = f"Microsoft.UI.Xaml_{arch}.appx"
|
||||
out_file = download_dir / out_file_name
|
||||
# elif re.match(f"Microsoft\.VCLibs\..+\.UWPDesktop_.*_{arch}_.*\.appx", f):
|
||||
# out_file_name = f"Microsoft.VCLibs.140.00.UWPDesktop_{arch}.appx"
|
||||
# out_file = download_dir / out_file_name
|
||||
elif re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", f):
|
||||
out_file_name = f"wsa-{arch}-{release_type}.zip"
|
||||
out_file = download_dir / out_file_name
|
||||
else:
|
||||
continue
|
||||
out = requests.post(
|
||||
download_files = {}
|
||||
|
||||
|
||||
def send_req(i, v, out_file_name):
|
||||
out = session.post(
|
||||
'https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured',
|
||||
data=file_content.format(i, v, release_type),
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'},
|
||||
verify=False
|
||||
data=FE3_file_content.format(user, i, v, release_type),
|
||||
headers={'Content-Type': 'application/soap+xml; charset=utf-8'}
|
||||
)
|
||||
doc = minidom.parseString(out.text)
|
||||
for l in doc.getElementsByTagName("FileLocation"):
|
||||
url = l.getElementsByTagName("Url")[0].firstChild.nodeValue
|
||||
if len(url) != 99:
|
||||
print(f"download link: {url} to {out_file}", flush=True)
|
||||
tmpdownlist.writelines(url + '\n')
|
||||
tmpdownlist.writelines(f' dir={download_dir}\n')
|
||||
tmpdownlist.writelines(f' out={out_file_name}\n')
|
||||
tmpdownlist.writelines(f'https://aka.ms/Microsoft.VCLibs.{arch}.14.00.Desktop.appx\n')
|
||||
tmpdownlist.writelines(f' dir={download_dir}\n')
|
||||
download_files[out_file_name] = url
|
||||
|
||||
|
||||
threads = []
|
||||
wsa_build_ver = 0
|
||||
for filename, values in identities.items():
|
||||
if re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", filename):
|
||||
tmp_wsa_build_ver = re.search(
|
||||
u'\d{4}.\d{5}.\d{1,}.\d{1,}', filename).group()
|
||||
if (wsa_build_ver == 0):
|
||||
wsa_build_ver = tmp_wsa_build_ver
|
||||
elif version.parse(wsa_build_ver) < version.parse(tmp_wsa_build_ver):
|
||||
wsa_build_ver = tmp_wsa_build_ver
|
||||
for filename, values in identities.items():
|
||||
if re.match(f"Microsoft\.UI\.Xaml\..*_{arch}_.*\.appx", filename):
|
||||
out_file_name = f"{values[1]}_{arch}.appx"
|
||||
out_file = download_dir / out_file_name
|
||||
elif re.match(f"Microsoft\.VCLibs\..+\.UWPDesktop_.*_{arch}_.*\.appx", filename):
|
||||
out_file_name = f"{values[1]}_{arch}.appx"
|
||||
out_file = download_dir / out_file_name
|
||||
elif re.match(f"Microsoft\.VCLibs\..+_.*_{arch}_.*\.appx", filename):
|
||||
out_file_name = f"{values[1]}_{arch}.appx"
|
||||
out_file = download_dir / out_file_name
|
||||
elif not skip_wsa_download and re.match(f"MicrosoftCorporationII\.WindowsSubsystemForAndroid_.*\.msixbundle", filename):
|
||||
tmp_wsa_build_ver = re.search(
|
||||
u'\d{4}.\d{5}.\d{1,}.\d{1,}', filename).group()
|
||||
if (wsa_build_ver != tmp_wsa_build_ver):
|
||||
continue
|
||||
version_splitted = wsa_build_ver.split(".")
|
||||
major_ver = version_splitted[0]
|
||||
minor_ver = version_splitted[1]
|
||||
build_ver = version_splitted[2]
|
||||
revision_ver = version_splitted[3]
|
||||
out_file_name = f"wsa-{release_type}.zip"
|
||||
out_file = download_dir / out_file_name
|
||||
else:
|
||||
continue
|
||||
th = Thread(target=send_req, args=(
|
||||
values[0][0], values[0][1], out_file_name))
|
||||
threads.append(th)
|
||||
th.daemon = True
|
||||
th.start()
|
||||
for th in threads:
|
||||
th.join()
|
||||
print(f'WSA Build Version={wsa_build_ver}\n', flush=True)
|
||||
for key, value in download_files.items():
|
||||
print(f"download link: {value}\npath: {download_dir / key}\n", flush=True)
|
||||
tmpdownlist.writelines(value + '\n')
|
||||
tmpdownlist.writelines(f' dir={download_dir}\n')
|
||||
tmpdownlist.writelines(f' out={key}\n')
|
||||
tmpdownlist.close()
|
||||
|
|
2
scripts/init.lsp.magisk.rc
Normal file
2
scripts/init.lsp.magisk.rc
Normal file
|
@ -0,0 +1,2 @@
|
|||
on post-fs-data
|
||||
exec u:r:magisk:s0 0 0 -- /system/bin/sh ${MAGISKTMP}/post-fs-data.sh
|
195
scripts/install_deps.sh
Executable file
195
scripts/install_deps.sh
Executable file
|
@ -0,0 +1,195 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
# MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2023 LSPosed Contributors
|
||||
#
|
||||
|
||||
if [ ! "$BASH_VERSION" ]; then
|
||||
echo "Please do not use sh to run this script, just execute it directly" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
abort() {
|
||||
[ "$1" ] && echo "ERROR: $1"
|
||||
echo "Dependencies: an error has occurred, exit"
|
||||
exit 1
|
||||
}
|
||||
require_su() {
|
||||
if test "$(id -u)" != "0"; then
|
||||
if [ "$(sudo id -u)" != "0" ]; then
|
||||
echo "sudo is required to run this script"
|
||||
abort
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and ensuring dependencies"
|
||||
check_dependencies() {
|
||||
command -v whiptail >/dev/null 2>&1 || command -v dialog >/dev/null 2>&1 || NEED_INSTALL+=("whiptail")
|
||||
command -v pip >/dev/null 2>&1 || NEED_INSTALL+=("python3-pip")
|
||||
command -v aria2c >/dev/null 2>&1 || NEED_INSTALL+=("aria2")
|
||||
command -v 7z >/dev/null 2>&1 || NEED_INSTALL+=("p7zip-full")
|
||||
command -v unzip >/dev/null 2>&1 || NEED_INSTALL+=("unzip")
|
||||
}
|
||||
check_dependencies
|
||||
osrel=$(sed -n '/^ID_LIKE=/s/^.*=//p' /etc/os-release)
|
||||
declare -A os_pm_install
|
||||
# os_pm_install["/etc/redhat-release"]=yum
|
||||
os_pm_install["/etc/arch-release"]=pacman
|
||||
os_pm_install["/etc/gentoo-release"]=emerge
|
||||
os_pm_install["/etc/SuSE-release"]=zypper
|
||||
os_pm_install["/etc/debian_version"]=apt-get
|
||||
# os_pm_install["/etc/alpine-release"]=apk
|
||||
|
||||
declare -A PM_UPDATE_MAP
|
||||
PM_UPDATE_MAP["yum"]="check-update"
|
||||
PM_UPDATE_MAP["pacman"]="-Syu --noconfirm"
|
||||
PM_UPDATE_MAP["emerge"]="-auDU1 @world"
|
||||
PM_UPDATE_MAP["zypper"]="ref"
|
||||
PM_UPDATE_MAP["apt-get"]="update"
|
||||
PM_UPDATE_MAP["apk"]="update"
|
||||
|
||||
declare -A PM_INSTALL_MAP
|
||||
PM_INSTALL_MAP["yum"]="install -y"
|
||||
PM_INSTALL_MAP["pacman"]="-S --noconfirm --needed"
|
||||
PM_INSTALL_MAP["emerge"]="-a"
|
||||
PM_INSTALL_MAP["zypper"]="in -y"
|
||||
PM_INSTALL_MAP["apt-get"]="install -y"
|
||||
PM_INSTALL_MAP["apk"]="add"
|
||||
|
||||
declare -A PM_UPGRADE_MAP
|
||||
PM_UPGRADE_MAP["apt-get"]="upgrade -y"
|
||||
PM_UPGRADE_MAP["zypper"]="up -y"
|
||||
|
||||
check_package_manager() {
|
||||
for f in "${!os_pm_install[@]}"; do
|
||||
if [[ -f $f ]]; then
|
||||
PM="${os_pm_install[$f]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "$osrel" = *"suse"* ]]; then
|
||||
PM="zypper"
|
||||
fi
|
||||
if [ -n "$PM" ]; then
|
||||
readarray -td ' ' UPDATE_OPTION <<<"${PM_UPDATE_MAP[$PM]} "
|
||||
unset 'UPDATE_OPTION[-1]'
|
||||
readarray -td ' ' INSTALL_OPTION <<<"${PM_INSTALL_MAP[$PM]} "
|
||||
unset 'INSTALL_OPTION[-1]'
|
||||
readarray -td ' ' UPGRADE_OPTION <<<"${PM_UPGRADE_MAP[$PM]} "
|
||||
unset 'UPGRADE_OPTION[-1]'
|
||||
fi
|
||||
}
|
||||
|
||||
check_package_manager
|
||||
require_su
|
||||
if [ -z "$PM" ]; then
|
||||
echo "Unable to determine package manager: Unsupported distros"
|
||||
abort
|
||||
elif [[ "$PM" =~ pacman|emerge ]]; then
|
||||
[ "$PM" = "emerge" ] && (sudo emerge -qoO aria2[adns] || abort)
|
||||
i=30
|
||||
while ((i-- > 1)) &&
|
||||
! read -r -sn 1 -t 1 -p $'\r:: Proceed with full system upgrade? Cancel after '$i$'s.. [y/N]\e[0K ' answer; do
|
||||
:
|
||||
done
|
||||
[[ $answer == [yY] ]] && answer=Yes || answer=No
|
||||
echo "$answer"
|
||||
case "$answer" in
|
||||
Yes)
|
||||
if ! (sudo "$PM" "${UPDATE_OPTION[@]}" ca-certificates); then abort; fi
|
||||
;;
|
||||
*)
|
||||
abort "Operation cancelled by user"
|
||||
;;
|
||||
esac
|
||||
else
|
||||
if ! (sudo "$PM" "${UPDATE_OPTION[@]}" && sudo "$PM" "${UPGRADE_OPTION[@]}" ca-certificates); then abort; fi
|
||||
fi
|
||||
|
||||
if [ -n "${NEED_INSTALL[*]}" ]; then
|
||||
if [ "$PM" = "zypper" ]; then
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL[*]}
|
||||
{
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//whiptail/dialog} 2>&1
|
||||
} >>/dev/null
|
||||
|
||||
readarray -td ' ' NEED_INSTALL <<<"$NEED_INSTALL_FIX "
|
||||
unset 'NEED_INSTALL[-1]'
|
||||
elif [ "$PM" = "apk" ]; then
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL[*]}
|
||||
readarray -td ' ' NEED_INSTALL <<<"${NEED_INSTALL_FIX//p7zip-full/p7zip} "
|
||||
unset 'NEED_INSTALL[-1]'
|
||||
elif [ "$PM" = "pacman" ]; then
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL[*]}
|
||||
{
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//whiptail/libnewt} 2>&1
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//python3-pip/python-pip} 2>&1
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//p7zip-full/p7zip} 2>&1
|
||||
} >>/dev/null
|
||||
|
||||
readarray -td ' ' NEED_INSTALL <<<"$NEED_INSTALL_FIX "
|
||||
unset 'NEED_INSTALL[-1]'
|
||||
elif [ "$PM" = "emerge" ]; then
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL[*]}
|
||||
{
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//whiptail/dialog} 2>&1
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//python3-pip/dev-python/pip} 2>&1
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//p7zip-full/p7zip} 2>&1
|
||||
} >>/dev/null
|
||||
|
||||
readarray -td ' ' NEED_INSTALL <<<"$NEED_INSTALL_FIX "
|
||||
unset 'NEED_INSTALL[-1]'
|
||||
fi
|
||||
if ! (sudo "$PM" "${INSTALL_OPTION[@]}" "${NEED_INSTALL[@]}"); then abort; fi
|
||||
|
||||
fi
|
||||
|
||||
python_version=$(python3 -c 'import sys;print("{0}{1}".format(*(sys.version_info[:2])))')
|
||||
PYTHON_VENV_DIR="$(dirname "$PWD")/python3-env"
|
||||
if [ "$python_version" -ge 311 ] || [ -f "$PYTHON_VENV_DIR/bin/activate" ]; then
|
||||
python3 -c "import venv" >/dev/null 2>&1 || {
|
||||
case "$PM" in
|
||||
zypper)
|
||||
if ! (sudo "$PM" "${INSTALL_OPTION[@]}" "python3-venvctrl"); then
|
||||
abort
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if ! (sudo "$PM" "${INSTALL_OPTION[@]}" "python3-venv"); then
|
||||
abort
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
echo "Creating python3 virtual env"
|
||||
python3 -m venv --system-site-packages "$PYTHON_VENV_DIR" || {
|
||||
echo "Failed to upgrade python3 virtual env, clear and recreate"
|
||||
python3 -m venv --clear --system-site-packages "$PYTHON_VENV_DIR" || abort "Failed to create python3 virtual env"
|
||||
}
|
||||
fi
|
||||
if [ -f "$PYTHON_VENV_DIR/bin/activate" ]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "$PYTHON_VENV_DIR"/bin/activate || abort "Failed to activate python3 virtual env"
|
||||
python3 -c "import pkg_resources; pkg_resources.require(open('requirements.txt',mode='r'))" &>/dev/null || {
|
||||
echo "Installing Python3 dependencies"
|
||||
python3 -m pip install -r requirements.txt || abort "Failed to install python3 dependencies"
|
||||
}
|
||||
deactivate
|
||||
else
|
||||
python3 -m pip install -r requirements.txt -q || abort "Failed to install python3 dependencies"
|
||||
fi
|
120
scripts/magisk_debug.sh
Normal file
120
scripts/magisk_debug.sh
Normal file
|
@ -0,0 +1,120 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is part of MagiskOnWSALocal.
|
||||
#
|
||||
# MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
if [ ! "$BASH_VERSION" ]; then
|
||||
echo "Please do not use sh to run this script, just execute it directly" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
HOST_ARCH=$(uname -m)
|
||||
if [ "$HOST_ARCH" != "x86_64" ] && [ "$HOST_ARCH" != "aarch64" ]; then
|
||||
echo "Unsupported architectures: $HOST_ARCH"
|
||||
exit 1
|
||||
fi
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
# export TMPDIR=$HOME/.cache/wsa
|
||||
if [ "$TMPDIR" ] && [ ! -d "$TMPDIR" ]; then
|
||||
mkdir -p "$TMPDIR"
|
||||
fi
|
||||
WORK_DIR=$(mktemp -d -t wsa-build-XXXXXXXXXX_) || exit 1
|
||||
|
||||
DOWNLOAD_DIR=../download
|
||||
PYTHON_VENV_DIR="$(dirname "$PWD")/python3-env"
|
||||
dir_clean() {
|
||||
rm -rf "${WORK_DIR:?}"
|
||||
if [ "$TMPDIR" ] && [ -d "$TMPDIR" ]; then
|
||||
echo "Cleanup Temp Directory"
|
||||
rm -rf "${TMPDIR:?}"
|
||||
unset TMPDIR
|
||||
fi
|
||||
if [ "$(python3 -c 'import sys ; print( 1 if sys.prefix != sys.base_prefix else 0 )')" = "1" ]; then
|
||||
echo "deactivate python3 venv"
|
||||
deactivate
|
||||
fi
|
||||
}
|
||||
trap dir_clean EXIT
|
||||
abort() {
|
||||
[ "$1" ] && echo -e "ERROR: $1"
|
||||
echo "Build: an error has occurred, exit"
|
||||
if [ -d "$WORK_DIR" ]; then
|
||||
echo -e "\nCleanup Work Directory"
|
||||
dir_clean
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
trap abort INT TERM
|
||||
# shellcheck disable=SC1091
|
||||
[ -f "$PYTHON_VENV_DIR/bin/activate" ] && {
|
||||
source "$PYTHON_VENV_DIR/bin/activate" || abort "Failed to activate virtual environment, please re-run install_deps.sh"
|
||||
}
|
||||
MAGISK_VER=$1
|
||||
ARCH=$2
|
||||
TARGET=$3
|
||||
if [ -z "$MAGISK_VER" ] || [ -z "$ARCH" ] || [ -z "$TARGET" ]; then
|
||||
echo "Usage: $0 <release|debug> <x64|arm64> <initrd>"
|
||||
exit 1
|
||||
fi
|
||||
MAGISK_ZIP=magisk-$MAGISK_VER.zip
|
||||
MAGISK_PATH=$DOWNLOAD_DIR/$MAGISK_ZIP
|
||||
if [ ! -f "$MAGISK_PATH" ]; then
|
||||
echo "Custom Magisk $MAGISK_ZIP not found"
|
||||
MAGISK_ZIP=app-$MAGISK_VER.apk
|
||||
echo -e "Fallback to $MAGISK_ZIP\n"
|
||||
MAGISK_PATH=$DOWNLOAD_DIR/$MAGISK_ZIP
|
||||
if [ ! -f "$MAGISK_PATH" ]; then
|
||||
abort "Custom Magisk $MAGISK_ZIP not found\nPlease put custom Magisk in $DOWNLOAD_DIR"
|
||||
fi
|
||||
fi
|
||||
echo "Extracting Magisk"
|
||||
if [ -f "$MAGISK_PATH" ]; then
|
||||
if ! python3 extractMagisk.py "$ARCH" "$MAGISK_PATH" "$WORK_DIR"; then
|
||||
abort "Unzip Magisk failed, is the download incomplete?"
|
||||
fi
|
||||
chmod +x "$WORK_DIR/magisk/magiskboot" || abort
|
||||
elif [ -z "${CUSTOM_MAGISK+x}" ]; then
|
||||
abort "The Magisk zip package does not exist, is the download incomplete?"
|
||||
else
|
||||
abort "The Magisk zip package does not exist, rename it to magisk-debug.zip and put it in the download folder."
|
||||
fi
|
||||
echo -e "done\n"
|
||||
echo "Integrating Magisk"
|
||||
SKIP="#"
|
||||
SINGLEABI="#"
|
||||
SKIPINITLD="#"
|
||||
if [ -f "$WORK_DIR/magisk/magisk64" ]; then
|
||||
"$WORK_DIR/magisk/magiskboot" compress=xz "$WORK_DIR/magisk/magisk64" "$WORK_DIR/magisk/magisk64.xz"
|
||||
"$WORK_DIR/magisk/magiskboot" compress=xz "$WORK_DIR/magisk/magisk32" "$WORK_DIR/magisk/magisk32.xz"
|
||||
unset SINGLEABI
|
||||
else
|
||||
"$WORK_DIR/magisk/magiskboot" compress=xz "$WORK_DIR/magisk/magisk" "$WORK_DIR/magisk/magisk.xz"
|
||||
unset SKIP
|
||||
fi
|
||||
if [ -f "$WORK_DIR/magisk/init-ld" ]; then
|
||||
"$WORK_DIR/magisk/magiskboot" compress=xz "$WORK_DIR/magisk/init-ld" "$WORK_DIR/magisk/init-ld.xz"
|
||||
unset SKIPINITLD
|
||||
fi
|
||||
"$WORK_DIR/magisk/magiskboot" compress=xz "$MAGISK_PATH" "$WORK_DIR/magisk/stub.xz"
|
||||
"$WORK_DIR/magisk/magiskboot" cpio "$TARGET" \
|
||||
"add 0750 /magiskinit $WORK_DIR/magisk/magiskinit" \
|
||||
"$SINGLEABI add 0644 overlay.d/sbin/magisk64.xz $WORK_DIR/magisk/magisk64.xz" \
|
||||
"$SINGLEABI add 0644 overlay.d/sbin/magisk32.xz $WORK_DIR/magisk/magisk32.xz" \
|
||||
"$SKIP add 0644 overlay.d/sbin/magisk.xz $WORK_DIR/magisk/magisk.xz" \
|
||||
"$SKIPINITLD add 0644 overlay.d/sbin/init-ld.xz $WORK_DIR/magisk/init-ld.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz $WORK_DIR/magisk/stub.xz" \
|
||||
|| abort "Unable to patch initrd"
|
44
scripts/post-fs-data.sh
Normal file
44
scripts/post-fs-data.sh
Normal file
|
@ -0,0 +1,44 @@
|
|||
#!/bin/sh
|
||||
MAGISKTMP=/sbin
|
||||
[ -d /sbin ] || MAGISKTMP=/debug_ramdisk
|
||||
MAGISKBIN=/data/adb/magisk
|
||||
if [ ! -d /data/adb ]; then
|
||||
mkdir -m 700 /data/adb
|
||||
chcon u:object_r:adb_data_file:s0 /data/adb
|
||||
fi
|
||||
if [ ! -d $MAGISKBIN ]; then
|
||||
# shellcheck disable=SC2174
|
||||
mkdir -p -m 755 $MAGISKBIN
|
||||
chcon u:object_r:system_file:s0 $MAGISKBIN
|
||||
fi
|
||||
ABI=$(getprop ro.product.cpu.abi)
|
||||
for file in busybox magiskpolicy magiskboot magiskinit; do
|
||||
[ -x "$MAGISKBIN/$file" ] || {
|
||||
unzip -d $MAGISKBIN -oj $MAGISKTMP/stub.apk "lib/$ABI/lib$file.so"
|
||||
mv $MAGISKBIN/lib$file.so $MAGISKBIN/$file
|
||||
chmod 755 "$MAGISKBIN/$file"
|
||||
}
|
||||
done
|
||||
for file in util_functions.sh boot_patch.sh; do
|
||||
[ -x "$MAGISKBIN/$file" ] || {
|
||||
unzip -d $MAGISKBIN -oj $MAGISKTMP/stub.apk "assets/$file"
|
||||
chmod 755 "$MAGISKBIN/$file"
|
||||
}
|
||||
done
|
||||
for file in "$MAGISKTMP"/*; do
|
||||
if echo "$file" | grep -Eq "lsp_.+\.img"; then
|
||||
foldername=$(basename "$file" .img)
|
||||
mkdir -p "$MAGISKTMP/$foldername"
|
||||
mount -t auto -o ro,loop "$file" "$MAGISKTMP/$foldername"
|
||||
"$MAGISKTMP/$foldername/post-fs-data.sh" &
|
||||
fi
|
||||
done
|
||||
wait
|
||||
for file in "$MAGISKTMP"/*; do
|
||||
if echo "$file" | grep -Eq "lsp_.+\.img"; then
|
||||
foldername=$(basename "$file" .img)
|
||||
umount "$MAGISKTMP/$foldername"
|
||||
rm -rf "${MAGISKTMP:?}/${foldername:?}"
|
||||
rm -f "$file"
|
||||
fi
|
||||
done
|
2
scripts/requirements.txt
Normal file
2
scripts/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
requests
|
||||
packaging
|
217
scripts/run.sh
217
scripts/run.sh
|
@ -15,117 +15,17 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Copyright (C) 2022 LSPosed Contributors
|
||||
# Copyright (C) 2024 LSPosed Contributors
|
||||
#
|
||||
|
||||
# DEBUG=--debug
|
||||
# CUSTOM_MAGISK=--magisk-custom
|
||||
|
||||
if [ ! "$BASH_VERSION" ]; then
|
||||
echo "Please do not use sh to run this script, just execute it directly" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
cd "$(dirname "$0")" || exit 1
|
||||
SUDO="$(which sudo 2>/dev/null)"
|
||||
abort() {
|
||||
echo "Dependencies: an error has occurred, exit"
|
||||
exit 1
|
||||
}
|
||||
require_su() {
|
||||
if test "$(whoami)" != "root"; then
|
||||
if [ -z "$SUDO" ] && [ "$($SUDO whoami)" != "root" ]; then
|
||||
echo "ROOT/SUDO is required to run this script"
|
||||
abort
|
||||
fi
|
||||
fi
|
||||
}
|
||||
echo "Checking and ensuring dependencies"
|
||||
check_dependencies() {
|
||||
command -v whiptail >/dev/null 2>&1 || command -v dialog >/dev/null 2>&1 || NEED_INSTALL+=("whiptail")
|
||||
command -v seinfo >/dev/null 2>&1 || NEED_INSTALL+=("setools")
|
||||
command -v lzip >/dev/null 2>&1 || NEED_INSTALL+=("lzip")
|
||||
command -v wine64 >/dev/null 2>&1 || NEED_INSTALL+=("wine")
|
||||
command -v winetricks >/dev/null 2>&1 || NEED_INSTALL+=("winetricks")
|
||||
command -v patchelf >/dev/null 2>&1 || NEED_INSTALL+=("patchelf")
|
||||
command -v resize2fs >/dev/null 2>&1 || NEED_INSTALL+=("e2fsprogs")
|
||||
command -v pip >/dev/null 2>&1 || NEED_INSTALL+=("python3-pip")
|
||||
command -v aria2c >/dev/null 2>&1 || NEED_INSTALL+=("aria2")
|
||||
command -v 7z > /dev/null 2>&1 || NEED_INSTALL+=("p7zip-full")
|
||||
command -v setfattr > /dev/null 2>&1 || NEED_INSTALL+=("attr")
|
||||
command -v xz > /dev/null 2>&1 || NEED_INSTALL+=("xz-utils")
|
||||
command -v unzip > /dev/null 2>&1 || NEED_INSTALL+=("unzip")
|
||||
}
|
||||
check_dependencies
|
||||
osrel=$(sed -n '/^ID_LIKE=/s/^.*=//p' /etc/os-release);
|
||||
declare -A os_pm_install;
|
||||
# os_pm_install["/etc/redhat-release"]=yum
|
||||
# os_pm_install["/etc/arch-release"]=pacman
|
||||
# os_pm_install["/etc/gentoo-release"]=emerge
|
||||
os_pm_install["/etc/SuSE-release"]=zypper
|
||||
os_pm_install["/etc/debian_version"]=apt-get
|
||||
# os_pm_install["/etc/alpine-release"]=apk
|
||||
|
||||
declare -A PM_UPDATE_MAP;
|
||||
PM_UPDATE_MAP["yum"]="check-update"
|
||||
PM_UPDATE_MAP["pacman"]="-Syu --noconfirm"
|
||||
PM_UPDATE_MAP["emerge"]="-auDN @world"
|
||||
PM_UPDATE_MAP["zypper"]="ref"
|
||||
PM_UPDATE_MAP["apt-get"]="update"
|
||||
PM_UPDATE_MAP["apk"]="update"
|
||||
./install_deps.sh || exit 1
|
||||
|
||||
declare -A PM_INSTALL_MAP;
|
||||
PM_INSTALL_MAP["yum"]="install -y"
|
||||
PM_INSTALL_MAP["pacman"]="-S --noconfirm --needed"
|
||||
PM_INSTALL_MAP["emerge"]="-a"
|
||||
PM_INSTALL_MAP["zypper"]="in -y"
|
||||
PM_INSTALL_MAP["apt-get"]="install -y"
|
||||
PM_INSTALL_MAP["apk"]="add"
|
||||
|
||||
check_package_manager() {
|
||||
for f in "${!os_pm_install[@]}"; do
|
||||
if [[ -f $f ]]; then
|
||||
PM="${os_pm_install[$f]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "$osrel" = *"suse"* ]]; then
|
||||
PM="zypper"
|
||||
fi
|
||||
if [ -n "$PM" ]; then
|
||||
readarray -td ' ' UPDATE_OPTION <<<"${PM_UPDATE_MAP[$PM]} "; unset 'UPDATE_OPTION[-1]';
|
||||
readarray -td ' ' INSTALL_OPTION <<<"${PM_INSTALL_MAP[$PM]} "; unset 'INSTALL_OPTION[-1]';
|
||||
fi
|
||||
}
|
||||
|
||||
check_package_manager
|
||||
if [ -n "${NEED_INSTALL[*]}" ]; then
|
||||
if [ -z "$PM" ]; then
|
||||
echo "Unable to determine package manager: Unsupported distros"
|
||||
abort
|
||||
else
|
||||
if [ "$PM" = "zypper" ]; then
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL[*]}
|
||||
{
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//setools/setools-console} 2>&1
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//whiptail/dialog} 2>&1
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL_FIX//xz-utils/xz} 2>&1
|
||||
} >> /dev/null
|
||||
|
||||
readarray -td ' ' NEED_INSTALL <<<"$NEED_INSTALL_FIX "; unset 'NEED_INSTALL[-1]';
|
||||
elif [ "$PM" = "apk" ]; then
|
||||
NEED_INSTALL_FIX=${NEED_INSTALL[*]}
|
||||
readarray -td ' ' NEED_INSTALL <<<"${NEED_INSTALL_FIX//p7zip-full/p7zip} "; unset 'NEED_INSTALL[-1]';
|
||||
fi
|
||||
require_su
|
||||
if ! ($SUDO "$PM" "${UPDATE_OPTION[@]}" && $SUDO "$PM" "${INSTALL_OPTION[@]}" "${NEED_INSTALL[@]}") then abort; fi
|
||||
fi
|
||||
fi
|
||||
pip list --disable-pip-version-check | grep -E "^requests " >/dev/null 2>&1 || python3 -m pip install requests
|
||||
|
||||
winetricks list-installed | grep -E "^msxml6" >/dev/null 2>&1 || {
|
||||
cp -r ../wine/.cache/* ~/.cache
|
||||
winetricks msxml6 || abort
|
||||
}
|
||||
WHIPTAIL=$(command -v whiptail 2>/dev/null)
|
||||
DIALOG=$(command -v dialog 2>/dev/null)
|
||||
DIALOG=${WHIPTAIL:-$DIALOG}
|
||||
|
@ -139,14 +39,31 @@ function Radiolist {
|
|||
|
||||
function YesNoBox {
|
||||
declare -A o="$1"
|
||||
local default
|
||||
[ "$2" ] && {
|
||||
[ "$2" = "no" ] && default="--defaultno"
|
||||
}
|
||||
shift
|
||||
$DIALOG --title "${o[title]}" --yesno "${o[text]}" 0 0
|
||||
$DIALOG --title "${o[title]}" $default --yesno "${o[text]}" 0 0
|
||||
}
|
||||
|
||||
function DialogBox {
|
||||
declare -A o="$1"
|
||||
shift
|
||||
$DIALOG --title "${o[title]}" --msgbox "${o[text]}" 0 0
|
||||
}
|
||||
intro="Welcome to MagiskOnWSA!
|
||||
|
||||
With this utility, you can integrate Magisk for WSA easily.
|
||||
Use arrow keys to navigate, and press space to select.
|
||||
Press enter to confirm.
|
||||
"
|
||||
DialogBox "([title]='Intro to MagiskOnWSA' \
|
||||
[text]='$intro')"
|
||||
|
||||
ARCH=$(
|
||||
Radiolist '([title]="Build arch"
|
||||
[default]="x64")' \
|
||||
\
|
||||
'x64' "X86_64" 'on' \
|
||||
'arm64' "AArch64" 'off'
|
||||
)
|
||||
|
@ -154,99 +71,53 @@ ARCH=$(
|
|||
RELEASE_TYPE=$(
|
||||
Radiolist '([title]="WSA release type"
|
||||
[default]="retail")' \
|
||||
\
|
||||
'retail' "Stable Channel" 'on' \
|
||||
'release preview' "Release Preview Channel" 'off' \
|
||||
'insider slow' "Beta Channel" 'off' \
|
||||
'insider fast' "Dev Channel" 'off'
|
||||
)
|
||||
declare -A RELEASE_TYPE_MAP=(["retail"]="retail" ["release preview"]="RP" ["insider slow"]="WIS" ["insider fast"]="WIF")
|
||||
COMMAND_LINE=(--arch "$ARCH" --release-type "${RELEASE_TYPE_MAP[$RELEASE_TYPE]}")
|
||||
if (YesNoBox '([title]="Root" [text]="Do you want to Root WSA?")'); then
|
||||
ROOT_SOL=$(
|
||||
Radiolist '([title]="Root solution"
|
||||
[default]="magisk")' \
|
||||
'magisk' "Magisk" 'on' \
|
||||
'kernelsu' "KernelSU" 'off'
|
||||
)
|
||||
COMMAND_LINE+=(--root-sol "$ROOT_SOL")
|
||||
fi
|
||||
|
||||
if [ -z "${CUSTOM_MAGISK+x}" ]; then
|
||||
if [ "$ROOT_SOL" = "magisk" ]; then
|
||||
MAGISK_VER=$(
|
||||
Radiolist '([title]="Magisk version"
|
||||
[default]="stable")' \
|
||||
\
|
||||
[default]="stable")' \
|
||||
'stable' "Stable Channel" 'on' \
|
||||
'beta' "Beta Channel" 'off' \
|
||||
'canary' "Canary Channel" 'off' \
|
||||
'debug' "Canary Channel Debug Build" 'off'
|
||||
)
|
||||
else
|
||||
MAGISK_VER=debug
|
||||
fi
|
||||
|
||||
if (YesNoBox '([title]="Install GApps" [text]="Do you want to install GApps?")'); then
|
||||
GAPPS_BRAND=$(
|
||||
Radiolist '([title]="Which GApps do you want to install?"
|
||||
[default]="MindTheGapps")' \
|
||||
\
|
||||
'OpenGApps' "" 'off' \
|
||||
'MindTheGapps' "" 'on'
|
||||
)
|
||||
else
|
||||
GAPPS_BRAND="none"
|
||||
fi
|
||||
if [ $GAPPS_BRAND = "OpenGApps" ]; then
|
||||
# TODO: Keep it pico since other variants of opengapps are unable to boot successfully
|
||||
if [ "$DEBUG" = "1" ]; then
|
||||
GAPPS_VARIANT=$(
|
||||
Radiolist '([title]="Variants of GApps"
|
||||
[default]="pico")' \
|
||||
\
|
||||
'super' "" 'off' \
|
||||
'stock' "" 'off' \
|
||||
'full' "" 'off' \
|
||||
'mini' "" 'off' \
|
||||
'micro' "" 'off' \
|
||||
'nano' "" 'off' \
|
||||
'pico' "" 'on' \
|
||||
'tvstock' "" 'off' \
|
||||
'tvmini' "" 'off'
|
||||
)
|
||||
else
|
||||
GAPPS_VARIANT=pico
|
||||
COMMAND_LINE+=(--magisk-ver "$MAGISK_VER")
|
||||
if (YesNoBox '([title]="Install GApps" [text]="Do you want to install GApps?")'); then
|
||||
COMMAND_LINE+=(--install-gapps)
|
||||
fi
|
||||
else
|
||||
GAPPS_VARIANT="pico"
|
||||
fi
|
||||
|
||||
if (YesNoBox '([title]="Remove Amazon Appstore" [text]="Do you want to keep Amazon Appstore?")'); then
|
||||
REMOVE_AMAZON=""
|
||||
else
|
||||
REMOVE_AMAZON="--remove-amazon"
|
||||
if (YesNoBox '([title]="Remove Amazon Appstore" [text]="Do you want to remove Amazon Appstore?")' no); then
|
||||
COMMAND_LINE+=(--remove-amazon)
|
||||
fi
|
||||
|
||||
ROOT_SOL=$(
|
||||
Radiolist '([title]="Root solution"
|
||||
[default]="magisk")' \
|
||||
\
|
||||
'magisk' "" 'on' \
|
||||
'none' "" 'off'
|
||||
)
|
||||
|
||||
if (YesNoBox '([title]="Compress output" [text]="Do you want to compress the output?")'); then
|
||||
COMPRESS_OUTPUT="--compress"
|
||||
else
|
||||
COMPRESS_OUTPUT=""
|
||||
fi
|
||||
if [ "$COMPRESS_OUTPUT" = "--compress" ]; then
|
||||
COMPRESS_FORMAT=$(
|
||||
Radiolist '([title]="Compress format"
|
||||
[default]="7z")' \
|
||||
\
|
||||
[default]="7z")' \
|
||||
'7z' "7-Zip" 'on' \
|
||||
'xz' "tar.xz" 'off' \
|
||||
'zip' "Zip" 'off'
|
||||
)
|
||||
)
|
||||
COMMAND_LINE+=(--compress-format "$COMPRESS_FORMAT")
|
||||
fi
|
||||
# if ! (YesNoBox '([title]="Off line mode" [text]="Do you want to enable off line mode?")'); then
|
||||
# OFFLINE="--offline"
|
||||
# else
|
||||
# OFFLINE=""
|
||||
# fi
|
||||
# OFFLINE="--offline"
|
||||
|
||||
clear
|
||||
declare -A RELEASE_TYPE_MAP=(["retail"]="retail" ["release preview"]="RP" ["insider slow"]="WIS" ["insider fast"]="WIF")
|
||||
COMMAND_LINE=(--arch "$ARCH" --release-type "${RELEASE_TYPE_MAP[$RELEASE_TYPE]}" --magisk-ver "$MAGISK_VER" --gapps-brand "$GAPPS_BRAND" --gapps-variant "$GAPPS_VARIANT" "$REMOVE_AMAZON" --root-sol "$ROOT_SOL" "$COMPRESS_OUTPUT" "$OFFLINE" "$DEBUG" "$CUSTOM_MAGISK" --compress-format "$COMPRESS_FORMAT")
|
||||
echo "COMMAND_LINE=${COMMAND_LINE[*]}"
|
||||
chmod +x ./build.sh
|
||||
./build.sh "${COMMAND_LINE[@]}"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,40 +1,37 @@
|
|||
<s:Envelope
|
||||
xmlns:a="http://www.w3.org/2005/08/addressing"
|
||||
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
|
||||
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
|
||||
<s:Header>
|
||||
<a:Action s:mustUnderstand="1">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetExtendedUpdateInfo2</a:Action>
|
||||
<a:MessageID>urn:uuid:2cc99c2e-3b3e-4fb1-9e31-0cd30e6f43a0</a:MessageID>
|
||||
<a:To s:mustUnderstand="1">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured</a:To>
|
||||
<o:Security s:mustUnderstand="1"
|
||||
<s:Header>
|
||||
<a:Action s:mustUnderstand="1">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetExtendedUpdateInfo2</a:Action>
|
||||
<a:MessageID>urn:uuid:2cc99c2e-3b3e-4fb1-9e31-0cd30e6f43a0</a:MessageID>
|
||||
<a:To s:mustUnderstand="1">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx/secured</a:To>
|
||||
<o:Security s:mustUnderstand="1"
|
||||
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
|
||||
<Timestamp
|
||||
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<Created>2017-08-01T00:29:01.868Z</Created>
|
||||
<Expires>2017-08-01T00:34:01.868Z</Expires>
|
||||
</Timestamp>
|
||||
<wuws:WindowsUpdateTicketsToken wsu:id="ClientMSA"
|
||||
<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<Created>2017-08-01T00:29:01.868Z</Created>
|
||||
<Expires>2017-08-01T00:34:01.868Z</Expires>
|
||||
</Timestamp>
|
||||
<wuws:WindowsUpdateTicketsToken wsu:id="ClientMSA"
|
||||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
xmlns:wuws="http://schemas.microsoft.com/msus/2014/10/WindowsUpdateAuthorization">
|
||||
<TicketType Name="MSA" Version="1.0" Policy="MBI_SSL">
|
||||
<Device>dAA9AEUAdwBBAHcAQQBzAE4AMwBCAEEAQQBVADEAYgB5AHMAZQBtAGIAZQBEAFYAQwArADMAZgBtADcAbwBXAHkASAA3AGIAbgBnAEcAWQBtAEEAQQBMAGoAbQBqAFYAVQB2AFEAYwA0AEsAVwBFAC8AYwBDAEwANQBYAGUANABnAHYAWABkAGkAegBHAGwAZABjADEAZAAvAFcAeQAvAHgASgBQAG4AVwBRAGUAYwBtAHYAbwBjAGkAZwA5AGoAZABwAE4AawBIAG0AYQBzAHAAVABKAEwARAArAFAAYwBBAFgAbQAvAFQAcAA3AEgAagBzAEYANAA0AEgAdABsAC8AMQBtAHUAcgAwAFMAdQBtAG8AMABZAGEAdgBqAFIANwArADQAcABoAC8AcwA4ADEANgBFAFkANQBNAFIAbQBnAFIAQwA2ADMAQwBSAEoAQQBVAHYAZgBzADQAaQB2AHgAYwB5AEwAbAA2AHoAOABlAHgAMABrAFgAOQBPAHcAYQB0ADEAdQBwAFMAOAAxAEgANgA4AEEASABzAEoAegBnAFQAQQBMAG8AbgBBADIAWQBBAEEAQQBpAGcANQBJADMAUQAvAFYASABLAHcANABBAEIAcQA5AFMAcQBhADEAQgA4AGsAVQAxAGEAbwBLAEEAdQA0AHYAbABWAG4AdwBWADMAUQB6AHMATgBtAEQAaQBqAGgANQBkAEcAcgBpADgAQQBlAEUARQBWAEcAbQBXAGgASQBCAE0AUAAyAEQAVwA0ADMAZABWAGkARABUAHoAVQB0AHQARQBMAEgAaABSAGYAcgBhAGIAWgBsAHQAQQBUAEUATABmAHMARQBGAFUAYQBRAFMASgB4ADUAeQBRADgAagBaAEUAZQAyAHgANABCADMAMQB2AEIAMgBqAC8AUgBLAGEAWQAvAHEAeQB0AHoANwBUAHYAdAB3AHQAagBzADYAUQBYAEIAZQA4AHMAZwBJAG8AOQBiADUAQQBCADcAOAAxAHMANgAvAGQAUwBFAHgATgBEAEQAYQBRAHoAQQBYAFAAWABCAFkAdQBYAFEARQBzAE8AegA4AHQAcgBpAGUATQBiAEIAZQBUAFkAOQBiAG8AQgBOAE8AaQBVADcATgBSAEYAOQAzAG8AVgArAFYAQQBiAGgAcAAwAHAAUgBQAFMAZQBmAEcARwBPAHEAdwBTAGcANwA3AHMAaAA5AEoASABNAHAARABNAFMAbgBrAHEAcgAyAGYARgBpAEMAUABrAHcAVgBvAHgANgBuAG4AeABGAEQAbwBXAC8AYQAxAHQAYQBaAHcAegB5AGwATABMADEAMgB3AHUAYgBtADUAdQBtAHAAcQB5AFcAYwBLAFIAagB5AGgAMgBKAFQARgBKAFcANQBnAFgARQBJADUAcAA4ADAARwB1ADIAbgB4AEwAUgBOAHcAaQB3AHIANwBXAE0AUgBBAFYASwBGAFcATQBlAFIAegBsADkAVQBxAGcALwBwAFgALwB2AGUATAB3AFMAawAyAFMAUwBIAGYAYQBLADYAagBhAG8AWQB1AG4AUgBHAHIAOABtAGIARQBvAEgAbABGADYASgBDAGEAYQBUAEIAWABCAGMAdgB1AGUAQwBKAG8AOQA4AGgAUgBBAHIARwB3ADQAKwBQAEgAZQBUAGIATgBTAEUAWABYAHoAdgBaADYAdQBXADUARQBBAGYAZABaAG0AUwA4ADgAVgBKAGMAWgBhAEYASwA3AHgAeABnADAAdwBvAG4ANwBoADAAeABDADYAWgBCADAAYwBZAGoATAByAC8ARwBlAE8AegA5AEcANABRAFUASAA5AEUAawB5ADAAZAB5AEYALwByAGUAVQAxAEkAeQBpAGEAcABwAGgATwBQADgAUwAyAHQANABCAHIAUABaAFgAVAB2AEMAMABQADcAegBPACsAZgBHAGsAeABWAG0AKwBVAGYAWgBiAFEANQA1AHMAdwBFAD0AJgBwAD0A</Device>
|
||||
</TicketType>
|
||||
</wuws:WindowsUpdateTicketsToken>
|
||||
</o:Security>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<GetExtendedUpdateInfo2
|
||||
xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
|
||||
<updateIDs>
|
||||
<UpdateIdentity>
|
||||
<UpdateID>{}</UpdateID>
|
||||
<RevisionNumber>{}</RevisionNumber>
|
||||
</UpdateIdentity>
|
||||
</updateIDs>
|
||||
<infoTypes>
|
||||
<XmlUpdateFragmentType>FileUrl</XmlUpdateFragmentType>
|
||||
<XmlUpdateFragmentType>FileDecryption</XmlUpdateFragmentType>
|
||||
</infoTypes>
|
||||
<deviceAttributes>BranchReadinessLevel=CB;CurrentBranch=rs_prerelease;OEMModel=Virtual Machine;FlightRing={};AttrDataVer=21;SystemManufacturer=Microsoft Corporation;InstallLanguage=en-US;OSUILocale=en-US;InstallationType=Client;FlightingBranchName=external;FirmwareVersion=Hyper-V UEFI Release v2.5;SystemProductName=Virtual Machine;OSSkuId=48;FlightContent=Branch;App=WU;OEMName_Uncleaned=Microsoft Corporation;AppVer=10.0.16184.1001;OSArchitecture=AMD64;SystemSKU=None;UpdateManagementGroup=2;IsFlightingEnabled=1;IsDeviceRetailDemo=0;TelemetryLevel=3;OSVersion=10.0.16184.1001;DeviceFamily=Windows.Desktop;</deviceAttributes>
|
||||
</GetExtendedUpdateInfo2>
|
||||
</s:Body>
|
||||
<TicketType Name="MSA" Version="1.0" Policy="MBI_SSL">
|
||||
<user>{}</user>
|
||||
</TicketType>
|
||||
</wuws:WindowsUpdateTicketsToken>
|
||||
</o:Security>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<GetExtendedUpdateInfo2 xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
|
||||
<updateIDs>
|
||||
<UpdateIdentity>
|
||||
<UpdateID>{}</UpdateID>
|
||||
<RevisionNumber>{}</RevisionNumber>
|
||||
</UpdateIdentity>
|
||||
</updateIDs>
|
||||
<infoTypes>
|
||||
<XmlUpdateFragmentType>FileUrl</XmlUpdateFragmentType>
|
||||
<XmlUpdateFragmentType>FileDecryption</XmlUpdateFragmentType>
|
||||
</infoTypes>
|
||||
<deviceAttributes>BranchReadinessLevel=CB;CurrentBranch=rs_prerelease;OEMModel=Virtual Machine;FlightRing={};AttrDataVer=21;SystemManufacturer=Microsoft Corporation;InstallLanguage=en-US;OSUILocale=en-US;InstallationType=Client;FlightingBranchName=external;FirmwareVersion=Hyper-V UEFI Release v2.5;SystemProductName=Virtual Machine;OSSkuId=48;FlightContent=Branch;App=WU;OEMName_Uncleaned=Microsoft Corporation;AppVer=10.0.22621.900;OSArchitecture=AMD64;SystemSKU=None;UpdateManagementGroup=2;IsFlightingEnabled=1;IsDeviceRetailDemo=0;TelemetryLevel=3;OSVersion=10.0.22621.900;DeviceFamily=Windows.Desktop;</deviceAttributes>
|
||||
</GetExtendedUpdateInfo2>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
||||
|
|
|
@ -1,27 +1,37 @@
|
|||
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2003/05/soap-envelope">
|
||||
<Header>
|
||||
<Action d3p1:mustUnderstand="1" xmlns:d3p1="http://www.w3.org/2003/05/soap-envelope" xmlns="http://www.w3.org/2005/08/addressing">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetCookie</Action>
|
||||
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:b9b43757-2247-4d7b-ae8f-a71ba8a22386</MessageID>
|
||||
<To d3p1:mustUnderstand="1" xmlns:d3p1="http://www.w3.org/2003/05/soap-envelope" xmlns="http://www.w3.org/2005/08/addressing">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx</To>
|
||||
<Security d3p1:mustUnderstand="1" xmlns:d3p1="http://www.w3.org/2003/05/soap-envelope" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
|
||||
<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<Created>2017-12-02T00:16:15.210Z</Created>
|
||||
<Expires>2017-12-29T06:25:43.943Z</Expires>
|
||||
</Timestamp>
|
||||
<WindowsUpdateTicketsToken d4p1:id="ClientMSA" xmlns:d4p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://schemas.microsoft.com/msus/2014/10/WindowsUpdateAuthorization">
|
||||
<TicketType Name="MSA" Version="1.0" Policy="MBI_SSL">
|
||||
<User />
|
||||
</TicketType>
|
||||
</WindowsUpdateTicketsToken>
|
||||
</Security>
|
||||
</Header>
|
||||
<Body>
|
||||
<GetCookie xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
|
||||
<oldCookie>
|
||||
</oldCookie>
|
||||
<lastChange>2015-10-21T17:01:07.1472913Z</lastChange>
|
||||
<currentTime>2017-12-02T00:16:15.217Z</currentTime>
|
||||
<protocolVersion>1.40</protocolVersion>
|
||||
</GetCookie>
|
||||
</Body>
|
||||
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns="http://www.w3.org/2003/05/soap-envelope">
|
||||
<Header>
|
||||
<Action d3p1:mustUnderstand="1"
|
||||
xmlns:d3p1="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns="http://www.w3.org/2005/08/addressing">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetCookie</Action>
|
||||
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:b9b43757-2247-4d7b-ae8f-a71ba8a22386</MessageID>
|
||||
<To d3p1:mustUnderstand="1"
|
||||
xmlns:d3p1="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns="http://www.w3.org/2005/08/addressing">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx</To>
|
||||
<Security d3p1:mustUnderstand="1"
|
||||
xmlns:d3p1="http://www.w3.org/2003/05/soap-envelope"
|
||||
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
|
||||
<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<Created>2017-12-02T00:16:15.210Z</Created>
|
||||
<Expires>2017-12-29T06:25:43.943Z</Expires>
|
||||
</Timestamp>
|
||||
<WindowsUpdateTicketsToken d4p1:id="ClientMSA"
|
||||
xmlns:d4p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
xmlns="http://schemas.microsoft.com/msus/2014/10/WindowsUpdateAuthorization">
|
||||
<TicketType Name="MSA" Version="1.0" Policy="MBI_SSL">
|
||||
<user>{}</user>
|
||||
</TicketType>
|
||||
</WindowsUpdateTicketsToken>
|
||||
</Security>
|
||||
</Header>
|
||||
<Body>
|
||||
<GetCookie xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
|
||||
<oldCookie>
|
||||
</oldCookie>
|
||||
<lastChange>2015-10-21T17:01:07.1472913Z</lastChange>
|
||||
<currentTime>2017-12-02T00:16:15.217Z</currentTime>
|
||||
<protocolVersion>1.40</protocolVersion>
|
||||
</GetCookie>
|
||||
</Body>
|
||||
</Envelope>
|
|
@ -1,5 +1,4 @@
|
|||
<s:Envelope
|
||||
xmlns:a="http://www.w3.org/2005/08/addressing"
|
||||
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
|
||||
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
|
||||
<s:Header>
|
||||
<a:Action s:mustUnderstand="1">http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/SyncUpdates</a:Action>
|
||||
|
@ -7,8 +6,7 @@
|
|||
<a:To s:mustUnderstand="1">https://fe3.delivery.mp.microsoft.com/ClientWebService/client.asmx</a:To>
|
||||
<o:Security s:mustUnderstand="1"
|
||||
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
|
||||
<Timestamp
|
||||
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
|
||||
<Created>2017-08-05T02:03:05.038Z</Created>
|
||||
<Expires>2017-08-05T02:08:05.038Z</Expires>
|
||||
</Timestamp>
|
||||
|
@ -16,14 +14,13 @@
|
|||
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
||||
xmlns:wuws="http://schemas.microsoft.com/msus/2014/10/WindowsUpdateAuthorization">
|
||||
<TicketType Name="MSA" Version="1.0" Policy="MBI_SSL">
|
||||
<Device>dAA9AEUAdwBBAHcAQQBzAE4AMwBCAEEAQQBVADEAYgB5AHMAZQBtAGIAZQBEAFYAQwArADMAZgBtADcAbwBXAHkASAA3AGIAbgBnAEcAWQBtAEEAQQBMAGoAbQBqAFYAVQB2AFEAYwA0AEsAVwBFAC8AYwBDAEwANQBYAGUANABnAHYAWABkAGkAegBHAGwAZABjADEAZAAvAFcAeQAvAHgASgBQAG4AVwBRAGUAYwBtAHYAbwBjAGkAZwA5AGoAZABwAE4AawBIAG0AYQBzAHAAVABKAEwARAArAFAAYwBBAFgAbQAvAFQAcAA3AEgAagBzAEYANAA0AEgAdABsAC8AMQBtAHUAcgAwAFMAdQBtAG8AMABZAGEAdgBqAFIANwArADQAcABoAC8AcwA4ADEANgBFAFkANQBNAFIAbQBnAFIAQwA2ADMAQwBSAEoAQQBVAHYAZgBzADQAaQB2AHgAYwB5AEwAbAA2AHoAOABlAHgAMABrAFgAOQBPAHcAYQB0ADEAdQBwAFMAOAAxAEgANgA4AEEASABzAEoAegBnAFQAQQBMAG8AbgBBADIAWQBBAEEAQQBpAGcANQBJADMAUQAvAFYASABLAHcANABBAEIAcQA5AFMAcQBhADEAQgA4AGsAVQAxAGEAbwBLAEEAdQA0AHYAbABWAG4AdwBWADMAUQB6AHMATgBtAEQAaQBqAGgANQBkAEcAcgBpADgAQQBlAEUARQBWAEcAbQBXAGgASQBCAE0AUAAyAEQAVwA0ADMAZABWAGkARABUAHoAVQB0AHQARQBMAEgAaABSAGYAcgBhAGIAWgBsAHQAQQBUAEUATABmAHMARQBGAFUAYQBRAFMASgB4ADUAeQBRADgAagBaAEUAZQAyAHgANABCADMAMQB2AEIAMgBqAC8AUgBLAGEAWQAvAHEAeQB0AHoANwBUAHYAdAB3AHQAagBzADYAUQBYAEIAZQA4AHMAZwBJAG8AOQBiADUAQQBCADcAOAAxAHMANgAvAGQAUwBFAHgATgBEAEQAYQBRAHoAQQBYAFAAWABCAFkAdQBYAFEARQBzAE8AegA4AHQAcgBpAGUATQBiAEIAZQBUAFkAOQBiAG8AQgBOAE8AaQBVADcATgBSAEYAOQAzAG8AVgArAFYAQQBiAGgAcAAwAHAAUgBQAFMAZQBmAEcARwBPAHEAdwBTAGcANwA3AHMAaAA5AEoASABNAHAARABNAFMAbgBrAHEAcgAyAGYARgBpAEMAUABrAHcAVgBvAHgANgBuAG4AeABGAEQAbwBXAC8AYQAxAHQAYQBaAHcAegB5AGwATABMADEAMgB3AHUAYgBtADUAdQBtAHAAcQB5AFcAYwBLAFIAagB5AGgAMgBKAFQARgBKAFcANQBnAFgARQBJADUAcAA4ADAARwB1ADIAbgB4AEwAUgBOAHcAaQB3AHIANwBXAE0AUgBBAFYASwBGAFcATQBlAFIAegBsADkAVQBxAGcALwBwAFgALwB2AGUATAB3AFMAawAyAFMAUwBIAGYAYQBLADYAagBhAG8AWQB1AG4AUgBHAHIAOABtAGIARQBvAEgAbABGADYASgBDAGEAYQBUAEIAWABCAGMAdgB1AGUAQwBKAG8AOQA4AGgAUgBBAHIARwB3ADQAKwBQAEgAZQBUAGIATgBTAEUAWABYAHoAdgBaADYAdQBXADUARQBBAGYAZABaAG0AUwA4ADgAVgBKAGMAWgBhAEYASwA3AHgAeABnADAAdwBvAG4ANwBoADAAeABDADYAWgBCADAAYwBZAGoATAByAC8ARwBlAE8AegA5AEcANABRAFUASAA5AEUAawB5ADAAZAB5AEYALwByAGUAVQAxAEkAeQBpAGEAcABwAGgATwBQADgAUwAyAHQANABCAHIAUABaAFgAVAB2AEMAMABQADcAegBPACsAZgBHAGsAeABWAG0AKwBVAGYAWgBiAFEANQA1AHMAdwBFAD0AJgBwAD0A</Device>
|
||||
<user>{}</user>
|
||||
</TicketType>
|
||||
</wuws:WindowsUpdateTicketsToken>
|
||||
</o:Security>
|
||||
</s:Header>
|
||||
<s:Body>
|
||||
<SyncUpdates
|
||||
xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
|
||||
<SyncUpdates xmlns="http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService">
|
||||
<cookie>
|
||||
<Expiration>2045-03-11T02:02:48Z</Expiration>
|
||||
<EncryptedData>{}</EncryptedData>
|
||||
|
@ -670,7 +667,7 @@
|
|||
</ClientPreferredLanguages>
|
||||
<ProductsParameters>
|
||||
<SyncCurrentVersionOnly>false</SyncCurrentVersionOnly>
|
||||
<DeviceAttributes>BranchReadinessLevel=CB;CurrentBranch=rs_prerelease;OEMModel=Virtual Machine;FlightRing={};AttrDataVer=21;SystemManufacturer=Microsoft Corporation;InstallLanguage=en-US;OSUILocale=en-US;InstallationType=Client;FlightingBranchName=external;FirmwareVersion=Hyper-V UEFI Release v2.5;SystemProductName=Virtual Machine;OSSkuId=48;FlightContent=Branch;App=WU;OEMName_Uncleaned=Microsoft Corporation;AppVer=10.0.16184.1001;OSArchitecture=AMD64;SystemSKU=None;UpdateManagementGroup=2;IsFlightingEnabled=1;IsDeviceRetailDemo=0;TelemetryLevel=3;OSVersion=10.0.16184.1001;DeviceFamily=Windows.Desktop;</DeviceAttributes>
|
||||
<DeviceAttributes>BranchReadinessLevel=CB;CurrentBranch=rs_prerelease;OEMModel=Virtual Machine;FlightRing={};AttrDataVer=21;SystemManufacturer=Microsoft Corporation;InstallLanguage=en-US;OSUILocale=en-US;InstallationType=Client;FlightingBranchName=external;FirmwareVersion=Hyper-V UEFI Release v2.5;SystemProductName=Virtual Machine;OSSkuId=48;FlightContent=Branch;App=WU;OEMName_Uncleaned=Microsoft Corporation;AppVer=10.0.22621.900;OSArchitecture=AMD64;SystemSKU=None;UpdateManagementGroup=2;IsFlightingEnabled=1;IsDeviceRetailDemo=0;TelemetryLevel=3;OSVersion=10.0.22621.900;DeviceFamily=Windows.Desktop;</DeviceAttributes>
|
||||
<CallerAttributes>Interactive=1;IsSeeker=0;</CallerAttributes>
|
||||
<Products/>
|
||||
</ProductsParameters>
|
||||
|
|
29
xml/priconfig.xml
Normal file
29
xml/priconfig.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!-- This file is part of MagiskOnWSALocal.
|
||||
|
||||
MagiskOnWSALocal is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
MagiskOnWSALocal is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with MagiskOnWSALocal. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright (C) 2023 LSPosed Contributors
|
||||
-->
|
||||
<resources targetOsVersion="10.0.0" majorVersion="1">
|
||||
<index root="\" startIndexAt="\">
|
||||
<default>
|
||||
<qualifier name="Language" value="en-US" />
|
||||
</default>
|
||||
<indexer-config type="folder" foldernameAsQualifier="true" filenameAsQualifier="true"
|
||||
qualifierDelimiter="." />
|
||||
<indexer-config type="PRI" />
|
||||
<indexer-config type="priinfo" />
|
||||
</index>
|
||||
</resources>
|
Loading…
Add table
Reference in a new issue