#!/usr/bin/env python3 """Convert INF AddReg sections into a Windows/Wine .reg file. Example: inf2reg.py --section APIReg --define 49000='C:\\windows\\speech' \ spchapi/SPCHAPI.INF > spchapi.reg """ import argparse import re import sys ROOTS = { "HKCR": "HKEY_CLASSES_ROOT", "HKLM": "HKEY_LOCAL_MACHINE", "HKCU": "HKEY_CURRENT_USER", "HKU": "HKEY_USERS", } def expand(text, defines): def repl(m): key = m.group(1) if key == "25": return defines.get("WINDOWS", r"C:\windows") return defines.get(key, m.group(0)) return re.sub(r"%(\w+)%", repl, text) def reg_type(flags, data): if not flags: return "REG_SZ" try: f = int(flags, 16) if flags.lower().startswith("0x") else int(flags) except ValueError: return "REG_SZ" if f & 0x00020000: return "REG_EXPAND_SZ" if f & 0x00010000: return "REG_MULTI_SZ" if f & 0x00000001: return "REG_BINARY" return "REG_SZ" def reg_escape(value): return value.replace("\\", "\\\\").replace('"', '\\"') def unquote(token): token = token.strip() if len(token) >= 2 and token[0] == '"' and token[-1] == '"': return token[1:-1] return token def main(): ap = argparse.ArgumentParser() ap.add_argument("inf") ap.add_argument("--section", action="append", required=True, help="AddReg section name (repeatable)") ap.add_argument("--define", action="append", default=[], help="ID=value, e.g. 49000=C:\\windows\\speech") args = ap.parse_args() defines = {"WINDOWS": r"C:\windows"} for item in args.define: k, v = item.split("=", 1) defines[k] = v wanted = set(args.section) section = None out = ["REGEDIT4", ""] with open(args.inf, "r", encoding="latin-1") as fh: for raw in fh: line = raw.strip() if not line or line.startswith(";"): continue m = re.match(r"^\[([^\]]+)\]$", line) if m: section = m.group(1) continue if section not in wanted: continue parts = [p.strip() for p in line.split(",")] if len(parts) < 4: continue root, key, name, flags = parts[0], parts[1], parts[2], parts[3] data = ",".join(parts[4:]) if len(parts) > 4 else "" if root.upper() not in ROOTS: continue data = expand(unquote(data), defines) name = expand(unquote(name), defines) if "%InstallPrompt%" in name: continue if not data: continue rtype = reg_type(flags.strip(), data) keypath = "\\".join( p for p in (ROOTS[root.upper()], expand(key, defines)) if p ) value = data if rtype == "REG_BINARY" else '"%s"' % reg_escape(data) out.append("[%s]" % keypath) out.append("%s=%s" % ('@' if not name else '"%s"' % name, value)) out.append("") sys.stdout.write("\n".join(out) + "\n") if __name__ == "__main__": main()