Delete installcab.py

This commit is contained in:
z0z0z 2019-04-30 05:19:26 +00:00 committed by GitHub
parent cbe5e25716
commit c5a0b17137
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 0 additions and 308 deletions

View File

@ -1,308 +0,0 @@
#! /usr/bin/env python2
import os
import sys
import subprocess
import tempfile
import shutil
import xml.etree.ElementTree
import re
tmpdir = None
#######################################
# Utils
def cleanup():
if not tmpdir:
return
if options['nocleanup']:
print("Not cleaning up. Find the files at %s" % tmpdir)
else:
shutil.rmtree(tmpdir)
def bad_exit(text):
print(text)
cleanup()
sys.exit(1)
def print_debug(text):
if options['debug']:
print(text)
#######################################
# Architecture helpers
arch_map = {
"amd64": "win64",
"x86": "win32",
"wow64": "wow64"
}
dest_map = {
"win64:win32": "Syswow64",
"win64:win64": "System32",
"win64:wow64": "System32",
"win32:win32": "System32"
}
def check_wineprefix_arch(prefix_path):
if not os.path.exists(prefix_path):
bad_exit("Wineprefix path does not exist! (%s)" % prefix_path)
system_reg_file = os.path.join(prefix_path, 'system.reg')
with open(system_reg_file) as f:
for line in f.readlines():
if line.startswith("#arch=win32"):
return 'win32'
elif line.startswith("#arch=win64"):
return 'win64'
bad_exit("Could not determine wineprefix arch!")
def get_system32_realdir(arch):
return dest_map[winearch+':'+arch]
def get_dll_destdir(dll_path):
arch = check_dll_arch(dll_path)
if arch == 'win32' and winearch == 'win64':
dest_dir = syswow64_path
elif arch == 'win64' and winearch == 'win32':
bad_exit("Invalid win64 assembly for win32 wineprefix!")
else:
dest_dir = system32_path
return dest_dir
def get_winebin(arch):
if (arch == 'win64' or arch == 'wow64') and winearch == 'win32':
bad_exit("Invalid win64 assembly for win32 wineprefix!")
elif arch == 'win32' or arch == 'wow64':
winebin = 'wine'
else:
winebin = 'wine64'
return winebin
def check_dll_arch(dll_path):
out = subprocess.check_output(['file', dll_path])
if 'x86-64' in out:
return 'win64'
else:
return 'win32'
#######################################
# Manifest processing
def replace_variables(value, arch):
if "$(" in value:
value = value.replace("$(runtime.help)", "C:\\windows\\help")
value = value.replace("$(runtime.inf)", "C:\\windows\\inf")
value = value.replace("$(runtime.wbem)", "C:\\windows\\wbem")
value = value.replace("$(runtime.windows)", "C:\\windows")
value = value.replace("$(runtime.ProgramFiles)", "C:\\windows\\Program Files")
value = value.replace("$(runtime.programFiles)", "C:\\windows\\Program Files")
value = value.replace("$(runtime.programFilesX86)", "C:\\windows\\Program Files (x86)")
value = value.replace("$(runtime.system32)", "C:\\windows\\%s" % get_system32_realdir(arch))
value = value.replace("$(runtime.drivers)", "C:\\windows\\%s\\drivers" % get_system32_realdir(arch))
value = value.replace("\\", "\\\\")
return value
def process_value(rv, arch):
attrs = rv.attrib
name = attrs["name"]
value = attrs["value"]
value_type = attrs["valueType"]
if not name.strip():
name = "@"
else:
name = "\"%s\"" % name
name = replace_variables(name, arch)
if value_type == 'REG_BINARY':
value = re.findall('..',value)
value = 'hex:'+",".join(value)
elif value_type == 'REG_DWORD':
value = "dword:%s" % value.replace("0x", "")
elif value_type == 'REG_QWORD':
value = "qword:%s" % value.replace("0x", "")
elif value_type == 'REG_NONE':
value = None
elif value_type == 'REG_EXPAND_SZ':
# not sure if we should replace this ones at this point:
# caps can vary in the pattern
value = value.replace("%SystemRoot%", "C:\\windows")
value = value.replace("%ProgramFiles%", "C:\\windows\\Program Files")
value = value.replace("%WinDir%", "C:\\windows")
value = value.replace("%ResourceDir%", "C:\\windows")
value = value.replace("%Public%", "C:\\users\\Public")
value = value.replace("%LocalAppData%", "C:\\windows\\Public\\Local Settings\\Application Data")
value = value.replace("%AllUsersProfile%", "C:\\windows")
value = value.replace("%UserProfile%", "C:\\windows")
value = value.replace("%ProgramData%", "C:\\ProgramData")
value = "\"%s\"" % value
elif value_type == 'REG_SZ':
value = "\"%s\"" % value
else:
print("warning unkown type: %s" % value_type)
value = "\"%s\"" % value
if value:
value = replace_variables(value, arch)
if options["stripdllpath"]:
if '.dll' in value:
value = value.lower().replace("c:\\\\windows\\\\system32\\\\", "")
value = value.lower().replace("c:\\\\windows\\\\syswow64\\\\", "")
return name, value
def process_key(key):
key = key.strip("\\")
key = key.replace("HKEY_CLASSES_ROOT", "HKEY_LOCAL_MACHINE\\Software\\Classes")
return key
def parse_manifest_arch(elmt):
registry_keys = elmt.findall("{urn:schemas-microsoft-com:asm.v3}assemblyIdentity")
if not len(registry_keys):
bad_exit("Can't find processor architecture")
arch = registry_keys[0].attrib["processorArchitecture"]
if not arch in arch_map:
bad_exit("Unknown processor architecture %s" % arch)
arch = arch_map[arch]
if (arch == 'win64' or arch == 'wow64') and winearch == 'win32':
bad_exit("Invalid 64 bit assembly for 32 bit system!")
return arch
def process_manifest(file_name):
out = ""
elmt = xml.etree.ElementTree.parse(file_name).getroot()
arch = parse_manifest_arch(elmt)
registry_keys = elmt.findall("{urn:schemas-microsoft-com:asm.v3}registryKeys")
if len(registry_keys):
for registry_key in registry_keys[0].getchildren():
key = process_key(registry_key.attrib["keyName"])
out += "[%s]\n" % key
for rv in registry_key.findall("{urn:schemas-microsoft-com:asm.v3}registryValue"):
name, value = process_value(rv, arch)
if not value is None:
out += "%s=%s\n"%(name,value)
out += "\n"
return (out, arch)
#######################################
# Installer Processing
def extract_from_installer(orig_file, dest_dir, component):
filter_str = "*%s*" % component
print("%s" % component.strip("_"))
cmd = ["cabextract", "-F", filter_str, "-d", dest_dir, orig_file]
subprocess.check_output(cmd)
output_files = [os.path.join(r,file) for r,d,f in os.walk(dest_dir) for file in f]
return output_files
def load_manifest(file_path):
file_name = os.path.basename(file_path)
reg_data, arch = process_manifest(file_path)
print("- %s (%s)" % (file_name, arch))
return reg_data, arch
def register_dll(dll_path):
if not options["register"]:
return
arch = check_dll_arch(dll_path)
winebin = get_winebin(arch)
cmd = ["regsvr32", os.path.basename(dll_path)]
subprocess.call(cmd)
def install_dll(dll_path):
if options["nodll"]:
return
dest_dir = get_dll_destdir(dll_path)
file_name = os.path.basename(dll_path)
print("- %s -> %s" % (file_name, dest_dir))
shutil.copy(dll_path, dest_dir)
register_dll(os.path.join(dest_dir, file_name))
def install_regfile(path, reg_file, arch):
if options["noreg"]:
return
winebin = get_winebin(arch)
print_debug(" install reg %s with %s" % (reg_file, winebin))
cmd = [winebin, "regedit", os.path.join(path, reg_file)]
subprocess.call(cmd)
def process_files(output_files):
reg_files = []
for file_path in output_files:
if file_path.endswith(".manifest"):
out = "Windows Registry Editor Version 5.00\n\n"
outdata, arch = load_manifest(file_path)
if outdata:
out += outdata
print_debug(" %s assembly" % arch)
with open(os.path.join(tmpdir, file_path+".reg"), "w") as f:
f.write(out)
reg_files.append((file_path, arch))
for file_path in output_files:
if file_path.endswith(".dll"):
install_dll(file_path)
for file_path, arch in reg_files:
install_regfile(tmpdir, file_path+".reg", arch)
#######################################
# Command line options
options = {'register': False, 'nocleanup': False, 'nodll': False, 'noreg': False, 'stripdllpath': False, 'debug': False}
def parse_command_line_opts(options):
app_argv = list(sys.argv)
for opt_key in options.keys():
opt_command = "--%s" % opt_key
if opt_command in app_argv:
options[opt_key] = True
app_argv.remove(opt_command)
return app_argv
#######################################
# Main
if __name__ == '__main__':
app_argv = parse_command_line_opts(options)
# sanity checks
if len(app_argv) < 3:
print("usage:")
print(" installcab.py [options] cabfile component [wineprefix_path]")
print("")
print("example:")
print(" installcab.py ~/.cache/winetricks/win7sp1/windows6.1-KB976932-X86.exe wmvdecod")
print("")
print("options:")
print(" --nocleanup: do not perform cleanup")
print(" --noreg: do not import registry entries")
print(" --nodll: do not install dlls into system dir")
print(" --register: register dlls with regsrv32")
print(" --stripdllpath: strip full path for dlls in registry so wine can find them anywhere")
sys.exit(0)
if len(app_argv) < 4 and not "WINEPREFIX" in os.environ:
bad_exit("You need to set WINEPREFIX for this to work!")
# setup
if len(app_argv) < 4:
wineprefix = os.environ["WINEPREFIX"]
else:
wineprefix = app_argv[3]
winearch = check_wineprefix_arch(wineprefix)
system32_path = os.path.join(wineprefix, 'drive_c', 'windows', 'system32')
syswow64_path = os.path.join(wineprefix, 'drive_c', 'windows', 'syswow64')
tmpdir = tempfile.mkdtemp()
cabfile = app_argv[1]
component = app_argv[2]
# processing
output_files = extract_from_installer(cabfile, tmpdir, component)
process_files(output_files)
# clean up
cleanup()