# Based on https://github.com/dfraze/binja_winmd/blob/main/main.py. Thank you, Dustin Fraze!
from __future__ import annotations

import json
import sys
import os
import logging
from collections import OrderedDict, defaultdict
from argparse import ArgumentParser
from pathlib import Path

import angr
from angr.sim_type import SimTypeFunction, SimTypeLong, SimTypeInt, SimTypeBottom
from angr.procedures.definitions import SimTypeCollection
from angr.errors import AngrMissingTypeError


api_namespaces = {}
altnames = set()


typelib = SimTypeCollection()
typelib.names = ["win32"]

# add Guid
guid_fields = OrderedDict()
guid_fields["Data1"] = angr.types.SimTypeInt(signed=False)
guid_fields["Data2"] = angr.types.SimTypeShort(signed=False)
guid_fields["Data3"] = angr.types.SimTypeShort(signed=False)
guid_fields["Data4"] = angr.types.SimTypeFixedSizeArray(angr.types.SimTypeChar(signed=False), length=8)
guid = angr.types.SimStruct(guid_fields, name="Guid", pack=True, align=1)
typelib.add("Guid", guid)

known_struct_names: set[str] = set()


def is_anonymous_struct(s_name: str) -> bool:
    return "anonymous" in s_name.lower()


def get_angr_type_from_name(name):
    if name == "Byte":
        return angr.types.SimTypeChar(signed=False, label="Byte")
    if name == "SByte":
        return angr.types.SimTypeChar(signed=True, label="SByte")
    if name == "Char":
        return angr.types.SimTypeChar(signed=True, label="Char")
    if name == "UInt16":
        return angr.types.SimTypeShort(signed=False, label="UInt16")
    if name == "Int16":
        return angr.types.SimTypeShort(signed=True, label="Int16")
    if name == "Int64":
        return angr.types.SimTypeLongLong(signed=True, label="Int64")
    if name == "UInt32":
        return angr.types.SimTypeInt(signed=False, label="UInt32")
    if name == "UInt64":
        return angr.types.SimTypeLongLong(signed=False, label="UInt64")
    if name == "Int32":
        return angr.types.SimTypeInt(signed=True, label="Int32")
    if name == "Single":
        return angr.types.SimTypeFloat(size=32)
    if name == "Double":
        return angr.types.SimTypeFloat(size=64)
    if name == "UIntPtr":
        return angr.types.SimTypePointer(angr.types.SimTypeInt(signed=False, label="UInt"), label="UIntPtr")
    if name == "IntPtr":
        return angr.types.SimTypePointer(angr.types.SimTypeInt(signed=True, label="Int"), label="IntPtr")
    if name == "Void":
        return angr.types.SimTypeBottom(label="Void")
    if name == "Boolean":
        return angr.types.SimTypeBool(label="Boolean")
    if name == "Guid":
        return angr.types.SimTypeRef("Guid", angr.types.SimStruct)
    print(f"Unhandled Native Type: {name}")
    sys.exit(-1)


def get_typeref_if_available(t: angr.types.SimType) -> angr.types.SimType:
    if isinstance(t, angr.types.SimStruct) and t.name and not is_anonymous_struct(t.name):
        # replace it with a SimTypeRef to avoid duplicate definition
        t = angr.types.SimTypeRef(t.name, angr.types.SimStruct)
    if t.label is not None and t.label in typelib:
        t = angr.types.SimTypeRef(t.label, t.__class__)
    return t


def handle_json_type(t, create_missing: bool = False):
    if t["Kind"] == "NativeTypedef":
        ty = handle_json_type(t["Def"], create_missing=create_missing)
        ty.label = t["Name"]
        return ty
    if t["Kind"] == "Native":
        return get_angr_type_from_name(t["Name"])
    if t["Kind"] == "PointerTo":
        pts_to = get_typeref_if_available(handle_json_type(t["Child"], create_missing=create_missing))
        return angr.types.SimTypePointer(pts_to)
    if t["Kind"] == "Array":
        elem = get_typeref_if_available(handle_json_type(t["Child"], create_missing=create_missing))
        if t["Shape"]:
            return angr.types.SimTypeFixedSizeArray(elem, length=int(t["Shape"]["Size"]))
        return angr.types.SimTypePointer(elem)
    if t["Kind"] == "ApiRef":
        try:
            named_type = typelib.get(t["Name"], bottom_on_missing=create_missing)
        except AngrMissingTypeError:
            if t["Name"] in known_struct_names:
                return angr.types.SimTypeRef(t["Name"], angr.types.SimStruct)
            raise
        return get_typeref_if_available(named_type)
    if t["Kind"] == "Struct":
        for nested_type in t["NestedTypes"]:
            typelib.add(nested_type["Name"], handle_json_type(nested_type, create_missing=create_missing))
        fields = OrderedDict()
        for field in t["Fields"]:
            child_type = get_typeref_if_available(handle_json_type(field["Type"], create_missing=create_missing))
            fields[field["Name"]] = child_type
        return angr.types.SimStruct(fields, name=t["Name"])
    if t["Kind"] == "LPArray":
        pts_to = get_typeref_if_available(handle_json_type(t["Child"], create_missing=create_missing))
        return angr.types.SimTypePointer(pts_to, label="LPArray")
    if t["Kind"] == "Union":
        for nested_type in t["NestedTypes"]:
            typelib.add(nested_type["Name"], handle_json_type(nested_type, create_missing=create_missing))
        members = {}
        for field in t["Fields"]:
            child_type = get_typeref_if_available(handle_json_type(field["Type"], create_missing=create_missing))
            members[field["Name"]] = child_type
        return angr.types.SimUnion(members)
    if t["Kind"] == "MissingClrType":
        return angr.types.SimTypeBottom(label="MissingClrType")
    print(f"Unhandled type: {t}")
    sys.exit(0)


def create_angr_type_from_json(t):
    if t["Kind"] == "NativeTypedef":
        new_typedef = handle_json_type(t)
        typelib.add(t["Name"], new_typedef)
    elif t["Kind"] == "Enum":
        # TODO: Handle Enums
        match t["IntegerBase"]:
            case "SByte":
                ty_cls = angr.types.SimTypeChar
                signed = True
            case "Byte":
                ty_cls = angr.types.SimTypeChar
                signed = False
            case "Int16":
                ty_cls = angr.types.SimTypeShort
                signed = True
            case "UInt16":
                ty_cls = angr.types.SimTypeShort
                signed = False
            case "Int32":
                ty_cls = angr.types.SimTypeInt
                signed = True
            case "UInt32":
                ty_cls = angr.types.SimTypeInt
                signed = False
            case "Int64":
                ty_cls = angr.types.SimTypeLongLong
                signed = True
            case "UInt64":
                ty_cls = angr.types.SimTypeLongLong
                signed = False
            case None:
                ty_cls = angr.types.SimTypeInt
                signed = False
            case _:
                raise NotImplementedError(f"Unsupported IntegerBase {t['IntegerBase']}")
        ty = ty_cls(signed=signed, label=t["Name"])
        typelib.add(t["Name"], ty)
    elif t["Kind"] == "Struct":
        known_struct_names.add(t["Name"])
        real_new_type = handle_json_type(t)
        typelib.add(t["Name"], real_new_type)
    elif t["Kind"] == "FunctionPointer":
        ret_type = handle_json_type(t["ReturnType"])
        args = []
        arg_names = []
        for param in t["Params"]:
            new_param = handle_json_type(param["Type"])
            args.append(new_param)
            arg_names.append(param["Name"])
        typelib.add(
            t["Name"], angr.types.SimTypePointer(angr.types.SimTypeFunction(args, ret_type, arg_names=arg_names))
        )
    elif t["Kind"] == "Com":
        # TODO: Handle Com
        typelib.add(t["Name"], angr.types.SimTypeBottom(label=t["Name"]))
    elif t["Kind"] == "ComClassID":
        return
    elif t["Kind"] == "Union":
        real_new_type = handle_json_type(t)
        typelib.add(t["Name"], real_new_type)
        return
    else:
        print(f"Found unknown type kind: {t['Kind']}")


def do_it(in_dir):
    p = Path(in_dir)

    files = p.glob("*.json")

    for file in files:
        logging.info("Found file %s", file)
        with open(file, encoding="utf-8-sig") as f:
            api_namespaces[file.stem] = json.load(f)

    logging.info("Making a bunch of types...")
    missing_types_last_round = set()
    while True:
        nosuchtype = 0
        missing_types = set()
        for metadata in api_namespaces.values():
            types = metadata["Types"]
            for t in types:
                try:
                    create_angr_type_from_json(t)
                except AngrMissingTypeError:
                    # skip this type for now
                    nosuchtype += 1
                    missing_types.add(t["Name"])
        logging.info("... missing %d types", nosuchtype)
        if nosuchtype == 0 or missing_types == missing_types_last_round:
            break
        missing_types_last_round = missing_types

    if missing_types_last_round:
        logging.info("Missing types: %s", missing_types_last_round)
    else:
        logging.info("All referenced types have been created")
    logging.info("Alright, now let's do some functions")

    i = 1
    func_count = 0
    parsed_cprotos = defaultdict(list)
    for namespace, metadata in api_namespaces.items():
        logging.debug("+++ %d/%d: Processing namespace %s", i, len(api_namespaces), namespace)
        i += 1
        funcs = metadata["Functions"]
        if namespace.startswith("Windows.Win32"):
            prefix = "win32"
        elif namespace.startswith("Windows.Wdk"):
            prefix = "wdk"
        else:
            raise NotImplementedError(f"Unsupported namespace {namespace}")
        for f in funcs:
            libname = f["DllImport"].lower()
            suffix = ""
            if libname.endswith((".dll", ".exe", ".sys")):
                suffix = libname[-3:]
                libname = libname[:-4]
            # special case: put all wdk_ntdll.dll APIs under ntoskrnl.exe to avoid conflict with user-space ntdll.dll
            if prefix == "wdk" and libname == "ntdll" and suffix == "dll":
                libname = "ntoskrnl"
                suffix = "exe"
            ret_type = handle_json_type(f["ReturnType"], create_missing=True)
            args = []
            arg_names = []
            for param in f["Params"]:
                new_param = handle_json_type(param["Type"], create_missing=True)
                assert new_param is not None, "This should not happen, please report this."
                args.append(new_param)
                arg_names.append(param["Name"])
            new_func = angr.types.SimTypeFunction(args, ret_type, arg_names=arg_names)
            new_func_name = f["Name"]
            parsed_cprotos[(prefix, libname, suffix)].append((new_func_name, new_func, ""))
            func_count += 1

    # Some missing function declarations
    missing_declarations = defaultdict(dict)

    missing_declarations[("wdk", "ntoskrnl", "exe")] = {
        "__fastfail": SimTypeFunction(
            [SimTypeInt(signed=False, label="Int")], SimTypeBottom(label="void"), arg_names=["code"]
        )
    }
    missing_declarations[("win32", "kernel32", "dll")] = {
        "InterlockedCompareExchange": SimTypeFunction((SimTypeLong(),) * 3, SimTypeLong()),
        "InterlockedCompareExchange64": SimTypeFunction((SimTypeLong(),) * 5, SimTypeLong()),
        "InterlockedDecrement": SimTypeFunction((SimTypeLong(),) * 1, SimTypeLong()),
        "InterlockedExchange": SimTypeFunction((SimTypeLong(),) * 2, SimTypeLong()),
        "InterlockedExchangeAdd": SimTypeFunction((SimTypeLong(),) * 2, SimTypeLong()),
        "InterlockedIncrement": SimTypeFunction((SimTypeLong(),) * 1, SimTypeLong()),
        "UTRegister": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegisterConsoleVDM": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegOpenUserClassesRoot": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "SortCloseHandle": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "WriteConsoleInputVDMW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "RegEnumValueW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "BaseDllReadWriteIniFile": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "NlsCheckPolicy": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegGetKeySecurity": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "lstrlen": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "NlsGetCacheUpdateCount": SimTypeFunction([], SimTypeLong(signed=True)),
        "OpenThreadToken": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "SetTermsrvAppInstallMode": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "GetConsoleFontInfo": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "GetCalendarMonthsInYear": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "WerpNotifyLoadStringResourceEx": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RemoveLocalAlternateComputerNameW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "SetVDMCurrentDirectories": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "SetConsoleInputExeNameA": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "RegDisablePredefinedCacheEx": SimTypeFunction([], SimTypeLong(signed=True)),
        "IdnToAscii": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "LoadAppInitDlls": SimTypeFunction([], SimTypeLong(signed=True)),
        "OpenConsoleW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "ExitVDM": SimTypeFunction([SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "RegNotifyChangeKeyValue": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "AddLocalAlternateComputerNameW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegOpenKeyExA": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RtlMoveMemory": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegFlushKey": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "RegUnLoadKeyA": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegisterConsoleIME": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegLoadMUIStringA": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegCreateKeyExW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "CheckForReadOnlyResource": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegRestoreKeyW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "lstrcpy": SimTypeFunction([SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "RegEnumKeyExW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "CreateProcessAsUserW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RtlZeroMemory": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "GetConsoleNlsMode": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegGetValueA": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "AdjustCalendarDate": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "BaseSetLastNTError": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "ShowConsoleCursor": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "BasepCheckWinSaferRestrictions": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "ReadConsoleInputExA": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegSetValueExW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegQueryValueExW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegDeleteValueA": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegOpenCurrentUser": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "CtrlRoutine": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "RtlFillMemory": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "VerifyConsoleIoHandle": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "EnumerateLocalComputerNamesW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "CloseProfileUserMapping": SimTypeFunction([], SimTypeLong(signed=True)),
        "GetEraNameCountedString": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "RegisterWaitForSingleObjectEx": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "DosPathToSessionPathW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegSaveKeyExA": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "CreateProcessInternalW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "OpenProfileUserMapping": SimTypeFunction([], SimTypeLong(signed=True)),
        "GetConsoleHardwareState": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "SetConsoleNlsMode": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "AddLocalAlternateComputerNameA": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "BasepCheckBadapp": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "GetConsoleKeyboardLayoutNameA": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "lstrcmpi": SimTypeFunction([SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "BaseFormatObjectAttributes": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "LZCloseFile": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "GetNamedPipeAttribute": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "BasepMapModuleHandle": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "SetNamedPipeAttribute": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "RegCreateKeyExA": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "SetConsoleOS2OemFormat": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "TermsrvAppInstallMode": SimTypeFunction([], SimTypeLong(signed=True)),
        "RemoveLocalAlternateComputerNameA": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "LZCreateFileW": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "NlsUpdateLocale": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegisterWowBaseHandlers": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "SetClientTimeZoneInformation": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "BaseCheckRunApp": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "BaseThreadInitThunk": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "UpdateCalendarDayOfWeek": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "SetConsoleMaximumWindowSize": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "ConvertNLSDayOfWeekToWin32DayOfWeek": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "ConvertCalDateTimeToSystemTime": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegDeleteKeyExW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)],
            SimTypeLong(signed=True),
        ),
        "ReplaceFile": SimTypeFunction(
            [
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
                SimTypeLong(signed=True),
            ],
            SimTypeLong(signed=True),
        ),
        "GetConsoleCharType": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "GetConsoleInputWaitHandle": SimTypeFunction([], SimTypeLong(signed=True)),
        "RestoreLastError": SimTypeFunction([SimTypeLong(signed=True)], SimTypeLong(signed=True)),
        "CompareCalendarDates": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "RegLoadKeyA": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "SetLocalPrimaryComputerNameW": SimTypeFunction(
            [SimTypeLong(signed=True), SimTypeLong(signed=True)], SimTypeLong(signed=True)
        ),
        "UnregisterConsoleIME": SimTypeFunction([], SimTypeLong(signed=True)),
