mirror of
https://github.com/keylase/nvidia-patch.git
synced 2024-11-09 19:48:20 +00:00
Merge pull request #682 from reloxx13/add_gh_action
Add github action for windows patches
This commit is contained in:
commit
af2616a252
15
.github/workflows/README.md
vendored
Normal file
15
.github/workflows/README.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# GitHub Actions usage
|
||||
|
||||
To create patches to a new driver version simply create a new release with the following name schema:
|
||||
- For DCH: `win-dch-536.67`
|
||||
- For Studio: `win-studio-536.67`
|
||||
- If you need to rerun append `-{try}` e.g. `win-dch-536.67-2`
|
||||
|
||||
Tagname same as release name.
|
||||
|
||||
If the patch file exist for a version, they will get deleted and recreated.
|
||||
|
||||
The patches will be added as asset to the release.
|
||||
|
||||
|
||||
> Currently only for windows10 patches
|
104
.github/workflows/gen_win_patches.yml
vendored
Normal file
104
.github/workflows/gen_win_patches.yml
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
name: Generate Windows patches
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- name: Check release name and OS
|
||||
id: check_release
|
||||
run: |
|
||||
release_name="${{ github.event.release.tag_name }}"
|
||||
echo "Release Name: $release_name"
|
||||
if [[ $release_name =~ (win)-(dch|studio)-([0-9]+\.[0-9]+(-[a-zA-Z]+)?)(-.+)? ]]; then
|
||||
os="${BASH_REMATCH[1]}"
|
||||
variant="${BASH_REMATCH[2]}"
|
||||
version="${BASH_REMATCH[3]}"
|
||||
echo "Operating System: $os"
|
||||
echo "Variant: $variant"
|
||||
echo "Version: $version"
|
||||
|
||||
if [ "$os" != "win" ]; then
|
||||
echo "Not a Windows release. Stopping the CI workflow."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$variant" == "dch" ]; then
|
||||
variant="DCH"
|
||||
fi
|
||||
|
||||
echo "OS=$os" >> $GITHUB_ENV
|
||||
echo "VARIANT=$variant" >> $GITHUB_ENV
|
||||
echo "VERSION=$version" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Invalid release name format. Must be in the format 'win-dch-123.45' or 'win-studio-123.45'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Delete Existing Files
|
||||
run: |
|
||||
echo "Deleting existing files if they exist"
|
||||
rm -f "${{ github.workspace }}/win/win10_x64/${{ env.VERSION }}/nvencodeapi64.1337"
|
||||
rm -f "${{ github.workspace }}/win/win10_x64/${{ env.VERSION }}/nvencodeapi.1337"
|
||||
echo "Existing files deleted successfully"
|
||||
|
||||
- name: Run autopatch.py
|
||||
run: |
|
||||
echo "Running autopatch.py with version ${{ env.VERSION }}"
|
||||
cd "${{ github.workspace }}/win/tools/autopatch"
|
||||
python autopatch.py ${{ env.VERSION }}
|
||||
echo "autopatch.py executed successfully"
|
||||
|
||||
- name: Run add_driver.py
|
||||
run: |
|
||||
echo "Running add_driver.py with variant ${{ env.VARIANT }} and version ${{ env.VERSION }}"
|
||||
cd "${{ github.workspace }}/tools/readme-autogen"
|
||||
python add_driver.py -W -P GeForce --variant ${{ env.VARIANT }} -w win10 ${{ env.VERSION }}
|
||||
echo "add_driver.py executed successfully"
|
||||
|
||||
- name: Run readme_autogen.py
|
||||
run: |
|
||||
echo "Running readme_autogen.py"
|
||||
cd "${{ github.workspace }}/tools/readme-autogen"
|
||||
python readme_autogen.py
|
||||
echo "readme_autogen.py executed successfully"
|
||||
|
||||
- name: Commit and push changes
|
||||
run: |
|
||||
echo "Committing and pushing changes"
|
||||
cd "${{ github.workspace }}"
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add -A
|
||||
git diff --quiet --exit-code --cached || git commit -m "${{ env.OS }}: add support for ${{ env.VARIANT }} driver ${{ env.VERSION }}"
|
||||
git push origin master
|
||||
echo "Committed and pushed changes"
|
||||
|
||||
- name: Upload Patch Files
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
${{ github.workspace }}/win/win10_x64/${{ env.VERSION }}/nvencodeapi64.1337
|
||||
${{ github.workspace }}/win/win10_x64/${{ env.VERSION }}/nvencodeapi.1337
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAG_NAME: ${{ github.event.release.tag_name }}
|
1
win/tools/autopatch/.gitignore
vendored
1
win/tools/autopatch/.gitignore
vendored
@ -111,5 +111,4 @@ venv.bak/
|
||||
# dont commit 7zip files 7z.dll 7z.exe
|
||||
7z.*
|
||||
|
||||
temp/*
|
||||
!.gitempty
|
@ -1,16 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import os.path
|
||||
from binascii import unhexlify
|
||||
import xml.etree.ElementTree as ET
|
||||
import itertools
|
||||
import functools
|
||||
import itertools
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import urllib.request
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
from binascii import unhexlify
|
||||
|
||||
CRLF = b"\x0d\x0a"
|
||||
HEADER_FORMAT = b">%s"
|
||||
@ -19,7 +18,6 @@ OFFSET_ADJUSTMENT = 0xC00 # shift specific to x64dbg .1337 format
|
||||
|
||||
|
||||
def parse_args():
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generates .1337 patch for Nvidia drivers for Windows",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
@ -44,7 +42,7 @@ def parse_args():
|
||||
"nvencodeapi.dll",
|
||||
],
|
||||
help="name(s) of installed target file. Used for patch "
|
||||
"header")
|
||||
"header")
|
||||
parser.add_argument("-P", "--patch-name",
|
||||
nargs="+",
|
||||
default=[
|
||||
@ -72,7 +70,7 @@ def parse_args():
|
||||
parser.add_argument("-D", "--direct",
|
||||
action="store_true",
|
||||
help="supply patched library directly instead of "
|
||||
"installer file")
|
||||
"installer file")
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
@ -84,9 +82,11 @@ class ExtractException(Exception):
|
||||
class PatternNotFoundException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MultipleOccurencesException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class UnknownPlatformException(Exception):
|
||||
pass
|
||||
|
||||
@ -145,26 +145,26 @@ def make_patch(archive, *,
|
||||
arch_tgt,
|
||||
search,
|
||||
replacement,
|
||||
tmpdir,
|
||||
sevenzip="7z",
|
||||
direct=False):
|
||||
if direct:
|
||||
with open(archive, 'rb') as fo:
|
||||
f = fo.read()
|
||||
else:
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
with ExtractedTarget(archive,
|
||||
tmpdir,
|
||||
arch_tgt,
|
||||
sevenzip=sevenzip) as tgt:
|
||||
if tgt.endswith(".dll"):
|
||||
with open(tgt, 'rb') as fo:
|
||||
f = fo.read()
|
||||
else:
|
||||
f = expand(tgt, sevenzip=sevenzip)
|
||||
with ExtractedTarget(archive,
|
||||
tmpdir,
|
||||
arch_tgt,
|
||||
sevenzip=sevenzip) as tgt:
|
||||
if tgt.endswith(".dll"):
|
||||
with open(tgt, 'rb') as fo:
|
||||
f = fo.read()
|
||||
else:
|
||||
f = expand(tgt, sevenzip=sevenzip)
|
||||
offset = f.find(search)
|
||||
if offset == -1:
|
||||
raise PatternNotFoundException("Pattern not found.")
|
||||
if f[offset+len(search):].find(search) != -1:
|
||||
if f[offset + len(search):].find(search) != -1:
|
||||
raise MultipleOccurencesException("Multiple occurences of pattern found!")
|
||||
del f
|
||||
print("Pattern found @ %016X" % (offset,), file=sys.stderr)
|
||||
@ -181,7 +181,7 @@ def identify_driver(archive, *, sevenzip="7z"):
|
||||
manifest = extract_single_file(archive, "setup.cfg", sevenzip=sevenzip)
|
||||
root = ET.fromstring(manifest)
|
||||
version = root.attrib['version']
|
||||
product_type = root.find('./properties/string[@name="ProductType"]')\
|
||||
product_type = root.find('./properties/string[@name="ProductType"]') \
|
||||
.attrib['value']
|
||||
return version, product_type
|
||||
|
||||
@ -192,92 +192,109 @@ def format_patch(diff, filename):
|
||||
res += LINE_FORMAT % (offset + OFFSET_ADJUSTMENT, left, right)
|
||||
return res
|
||||
|
||||
|
||||
def patch_flow(installer_file, search, replacement, target, target_name, patch_name, *,
|
||||
direct=False, stdout=False, sevenzip="7z"):
|
||||
tempdir, direct=False, stdout=False, sevenzip="7z"):
|
||||
search = unhexlify(search)
|
||||
replacement = unhexlify(replacement)
|
||||
assert len(search) == len(replacement), "len() of search and replacement"\
|
||||
" is not equal"
|
||||
assert len(search) == len(replacement), "len() of search and replacement is not equal"
|
||||
|
||||
# check if installer file exists or try to download
|
||||
if not os.path.isfile(installer_file): #installer file does not exists, get url for download
|
||||
if not installer_file.startswith("http"): #installer_file is a version, parse to url
|
||||
filename = installer_file+"-desktop-win10-win11-64bit-international-dch-whql.exe"
|
||||
installer_file = "https://international.download.nvidia.com/Windows/"+installer_file+"/"+filename
|
||||
else: # installer_file is an url
|
||||
filename = os.path.basename(installer_file)
|
||||
# download installer and save in .temp
|
||||
# Check if installer file exists or try to download
|
||||
|
||||
if not os.path.isfile(os.path.join('temp', filename)): # check if file already downloaded
|
||||
print(f"Downloading... ( {installer_file} TO {os.path.join('temp', filename)} )")
|
||||
print("This may take a while (~800MB)")
|
||||
urllib.request.urlretrieve(installer_file, os.path.join('temp', filename))
|
||||
installer_file = os.path.join('temp', filename)
|
||||
print(f"Search for installer file `{installer_file}`...")
|
||||
if not os.path.isfile(installer_file):
|
||||
print("Installer file is not a file...")
|
||||
if not installer_file.startswith("http"):
|
||||
print("Installer file is not a URL...")
|
||||
|
||||
# Construct URL from version
|
||||
print("Installer file is a version!")
|
||||
filename = installer_file + "-desktop-win10-win11-64bit-international-dch-whql.exe"
|
||||
installer_url = f"https://international.download.nvidia.com/Windows/{installer_file}/{filename}"
|
||||
else:
|
||||
installer_file = os.path.join('temp', filename)
|
||||
print(f"Use downloaded file in `{installer_file}`")
|
||||
print("Installer file is a URL!")
|
||||
installer_url = installer_file
|
||||
|
||||
|
||||
|
||||
patch = make_patch(installer_file,
|
||||
arch_tgt=target,
|
||||
search=search,
|
||||
replacement=replacement,
|
||||
sevenzip=sevenzip,
|
||||
direct=direct)
|
||||
patch_content = format_patch(patch, target_name)
|
||||
if stdout:
|
||||
with open(sys.stdout.fileno(), mode='wb', closefd=False) as out:
|
||||
out.write(patch_content)
|
||||
elif direct:
|
||||
with open(patch_name, mode='wb') as out:
|
||||
out.write(patch_content)
|
||||
else:
|
||||
version, product_type = identify_driver(installer_file,
|
||||
sevenzip=sevenzip)
|
||||
drv_prefix = {
|
||||
"100": "quadro_",
|
||||
"103": "quadro_",
|
||||
"300": "",
|
||||
"301": "nsd_",
|
||||
"303": "", # DCH
|
||||
"304": "nsd_",
|
||||
}
|
||||
installer_name = os.path.basename(installer_file).lower()
|
||||
if 'winserv2008' in installer_name:
|
||||
os_prefix = 'ws2012_x64'
|
||||
elif 'winserv-2012' in installer_name:
|
||||
os_prefix = 'ws2012_x64'
|
||||
elif 'winserv-2016' in installer_name:
|
||||
os_prefix = 'ws2016_x64'
|
||||
elif 'win10' in installer_name:
|
||||
os_prefix = 'win10_x64'
|
||||
elif 'win7' in installer_name:
|
||||
os_prefix = 'win7_x64'
|
||||
if installer_url:
|
||||
try:
|
||||
file_path = os.path.join(tempdir, os.path.basename(installer_url))
|
||||
if not os.path.isfile(file_path):
|
||||
with urllib.request.urlopen(installer_url) as response, open(file_path, 'wb') as out_file:
|
||||
print(f"Downloading... ({installer_url} TO {file_path})")
|
||||
print("This may take a while (~800MB)")
|
||||
out_file.write(response.read())
|
||||
print("Download completed successfully!")
|
||||
installer_file = file_path
|
||||
else:
|
||||
print(f"Using downloaded file in '{file_path}'")
|
||||
installer_file = file_path
|
||||
except (urllib.error.URLError, Exception) as e:
|
||||
print(f"Failed to download the file: {e}")
|
||||
return
|
||||
except Exception as e:
|
||||
print(f"An error occurred during download: {str(e)}")
|
||||
return
|
||||
else:
|
||||
raise UnknownPlatformException("Can't infer platform from filename %s"
|
||||
% (repr(installer_name),))
|
||||
driver_name = drv_prefix[product_type] + version
|
||||
out_dir = os.path.join(
|
||||
os.path.dirname(
|
||||
os.path.abspath(__file__)), '..', '..', os_prefix, driver_name)
|
||||
os.makedirs(out_dir, 0o755, True)
|
||||
out_filename = os.path.join(out_dir,
|
||||
patch_name)
|
||||
with open(out_filename, 'xb') as out:
|
||||
out.write(patch_content)
|
||||
print(f"Invalid installer file or version: {installer_file}")
|
||||
return
|
||||
|
||||
# Rest of the code remains the same...
|
||||
patch = make_patch(installer_file,
|
||||
arch_tgt=target,
|
||||
search=search,
|
||||
replacement=replacement,
|
||||
tmpdir=tempdir,
|
||||
sevenzip=sevenzip,
|
||||
direct=direct)
|
||||
patch_content = format_patch(patch, target_name)
|
||||
|
||||
if stdout:
|
||||
sys.stdout.buffer.write(patch_content)
|
||||
elif direct:
|
||||
with open(patch_name, mode='wb') as out:
|
||||
out.write(patch_content)
|
||||
else:
|
||||
version, product_type = identify_driver(installer_file, sevenzip=sevenzip)
|
||||
drv_prefix = {
|
||||
"100": "quadro_",
|
||||
"103": "quadro_",
|
||||
"300": "",
|
||||
"301": "nsd_",
|
||||
"303": "", # DCH
|
||||
"304": "nsd_",
|
||||
}
|
||||
installer_name = os.path.basename(installer_file).lower()
|
||||
if 'winserv2008' in installer_name or 'winserv-2012' in installer_name:
|
||||
os_prefix = 'ws2012_x64'
|
||||
elif 'winserv-2016' in installer_name or 'win10' in installer_name:
|
||||
os_prefix = 'win10_x64'
|
||||
elif 'win7' in installer_name:
|
||||
os_prefix = 'win7_x64'
|
||||
else:
|
||||
raise UnknownPlatformException(f"Can't infer platform from filename {installer_name}")
|
||||
|
||||
driver_name = drv_prefix.get(product_type, "") + version
|
||||
out_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', os_prefix, driver_name)
|
||||
os.makedirs(out_dir, 0o755, exist_ok=True)
|
||||
out_filename = os.path.join(out_dir, patch_name)
|
||||
with open(out_filename, 'wb') as out:
|
||||
out.write(patch_content)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
if args.direct:
|
||||
combinations = zip(args.installer_file, args.search, args.replacement,
|
||||
args.target, args.target_name, args.patch_name)
|
||||
else:
|
||||
base_params = zip(args.search, args.replacement, args.target, args.target_name, args.patch_name)
|
||||
combinations = ((l,) + r for l, r in itertools.product(args.installer_file, base_params))
|
||||
for params in combinations:
|
||||
patch_flow(*params, direct=args.direct, stdout=args.stdout)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
print(f"Using tempdir `{tempdir}`")
|
||||
for params in combinations:
|
||||
patch_flow(*params, tempdir=tempdir, direct=args.direct, stdout=args.stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user