Delete installcab.py
This commit is contained in:
parent
cbe5e25716
commit
c5a0b17137
@ -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()
|
Loading…
Reference in New Issue
Block a user