Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд Заставляем работать инпут драйвер на 25H2

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
2 Фев 2020
Сообщения
248
Реакции
21
Спасибо огромное этому Человеку.

Первый код (НЕ РАБОТАЕТ на 24H2+):

Код:
Expand Collapse Copy
class DDXoft:
    def __init__(self):
        self.dll = None
        self.available = False
      
    def load(self, dll_path):
        try:
            # ПРОБЛЕМА: Прямая загрузка через WinDLL
            self.dll = ctypes.WinDLL(dll_path)
          
            # Настройка функций
            self.DD_btn = self.dll.DD_btn
            self.DD_btn.argtypes = [ctypes.c_int]
            self.DD_btn.restype = ctypes.c_int
          
            self.DD_key = self.dll.DD_key
            self.DD_key.argtypes = [ctypes.c_int, ctypes.c_int]
            self.DD_key.restype = ctypes.c_int
          
            # ПРОБЛЕМА: Инициализация сразу после загрузки
            result = self.DD_btn(0)
            if result == 1:
                self.available = True
                return 1
            return -1
        except Exception as e:
            return -2

Почему не работает:

Прямая загрузка через ctypes.WinDLL блокируется системой на Windows 11 24H2+
Отсутствует задержка между загрузкой и инициализацией
Нет обработки специфических флагов загрузки

Второй код (РАБОТАЕТ на 24H2+):

Код:
Expand Collapse Copy
def load_ddx():
    global DD_movR, DD_btn
    try:
        dll_path = os.path.abspath(DLL_NAME).encode("utf-8")
      
        # ИСПРАВЛЕНИЕ 1: Использование kernel32.LoadLibraryA
        kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
        load_library = kernel32.LoadLibraryA
        load_library.argtypes = [ctypes.c_char_p]
        load_library.restype = ctypes.c_void_p
      
        # ИСПРАВЛЕНИЕ 2: Загрузка через низкоуровневый API
        dll_handle = load_library(dll_path)

        if not dll_handle:
            raise RuntimeError("Не удалось загрузить ddxoft.dll")

        # ИСПРАВЛЕНИЕ 3: Получение адресов функций через GetProcAddress
        get_proc_address = kernel32.GetProcAddress
        get_proc_address.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
        get_proc_address.restype = ctypes.c_void_p

        def bind_function(name, restype, argtypes):
            addr = get_proc_address(dll_handle, name.encode("ascii"))
            if not addr:
                raise RuntimeError(f"Функция {name} не найдена в DLL")
            return ctypes.CFUNCTYPE(restype, *argtypes)(addr)

        DD_movR = bind_function("DD_movR", ctypes.c_int, [ctypes.c_int, ctypes.c_int])
        DD_btn = bind_function("DD_btn", ctypes.c_int, [ctypes.c_int])

        # ИСПРАВЛЕНИЕ 4: Проверка инициализации
        if DD_btn(0) != 1:
            raise RuntimeError("Драйвер ddxoft не активен или неподдерживаемая версия")

        print("[INFO] DLL успешно загружена и инициализирована")
        return True
    except Exception as e:
        print(f"[ERROR] Ошибка инициализации DLL: {e}")
        return False

Почему работает:

Использование низкоуровневого kernel32.LoadLibraryA вместо прямого ctypes.WinDLL
Получение адресов функций через GetProcAddress
Обход системной блокировки через системный API

Ключевые отличия (почему второй код работает):

Метод загрузки DLL

Первый код (проблемный):

Код:
Expand Collapse Copy
self.dll = ctypes.WinDLL(dll_path) # Высокоуровневый метод

Второй код (рабочий):

Код:
Expand Collapse Copy
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
load_library = kernel32.LoadLibraryA # Низкоуровневый API
dll_handle = load_library(dll_path)

Получение функций

Первый код:

Код:
Expand Collapse Copy
self.DD_btn = self.dll.DD_btn # Автоматическое связывание

Второй код:

Код:
Expand Collapse Copy
def bind_function(name, restype, argtypes):
    addr = get_proc_address(dll_handle, name.encode("ascii"))
    return ctypes.CFUNCTYPE(restype, *argtypes)(addr)

Обработка ошибок

Первый код:

Код:
Expand Collapse Copy
result = self.DD_btn(0) # Нет повторных попыток

Второй код:

Код:
Expand Collapse Copy
if DD_btn(0) != 1: # Единоразовая проверка с clear error message
    raise RuntimeError("Драйвер ddxoft не активен или неподдерживаемая версия")

Полное исправление для первого кода:

Код:
Expand Collapse Copy
class DDXoftFixed:
    def __init__(self):
        self.dll_handle = None
        self.dll = None
        self.available = False
        self.key_map = {
            'q': 301, 'w': 302, 'e': 303, 'r': 304, 'd': 403, 'f': 404,
            'z': 501, 'x': 502, 'c': 503
        }
      
    def load(self, dll_path):
        try:
            # ИСПРАВЛЕНИЕ: Используем kernel32.LoadLibraryA вместо прямого WinDLL
            kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
            load_library = kernel32.LoadLibraryA
            load_library.argtypes = [ctypes.c_char_p]
            load_library.restype = ctypes.c_void_p
            get_proc_address = kernel32.GetProcAddress
            get_proc_address.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
            get_proc_address.restype = ctypes.c_void_p
          
            # Загружаем DLL
            path_encoded = os.path.abspath(dll_path).encode("utf-8")
            self.dll_handle = load_library(path_encoded)
          
            if not self.dll_handle:
                raise RuntimeError("Не удалось загрузить ddxoft.dll")
          
            # ИСПРАВЛЕНИЕ: Функция для привязки методов
            def bind_function(name, restype, argtypes):
                addr = get_proc_address(self.dll_handle, name.encode("ascii"))
                if not addr:
                    raise RuntimeError(f"Функция {name} не найдена")
                return ctypes.CFUNCTYPE(restype, *argtypes)(addr)
          
            # Привязываем функции
            self.DD_btn = bind_function("DD_btn", ctypes.c_int, [ctypes.c_int])
            self.DD_key = bind_function("DD_key", ctypes.c_int, [ctypes.c_int, ctypes.c_int])
          
            # ИСПРАВЛЕНИЕ: Небольшая задержка перед инициализацией
            time.sleep(0.1)
          
            # Инициализация
            result = self.DD_btn(0)
            if result == 1:
                self.available = True
                return 1
            return -1
        except Exception as e:
            print(f"Error loading DDXoft: {e}")
            return -2
  
    def tap_key(self, key):
        if not self.available or key not in self.key_map:
            return False
        code = self.key_map[key]
        self.DD_key(code, 1)
        time.sleep(0.01)
        self.DD_key(code, 2)
        return True

# Функция инициализации для первого кода
def init_ddxoft_fixed():
    try:
        if not ctypes.windll.shell32.IsUserAnAdmin():
            messagebox.showerror("Ошибка", "Запустите от имени администратора")
            return False
          
        if not os.path.exists(DLL_NAME):
            if not download_ddx():
                messagebox.showerror("Ошибка", "Не удалось загрузить ddxoft.dll")
                return False
      
        # ИСПРАВЛЕНИЕ: Используем исправленный класс
        ddxoft_instance = DDXoftFixed()
        result = ddxoft_instance.load(os.path.abspath(DLL_NAME))
      
        if result != 1:
            messagebox.showerror("Ошибка", "Не удалось загрузить драйвер ddxoft")
            return False
          
        return True
    except Exception as e:
        messagebox.showerror("Ошибка", str(e))
        return False

Основные выводы:

1. Первый код использует высокоуровневый ctypes.WinDLL, который на Windows 11 24H2+ блокируется системой безопасности
2. Второй код использует низкоуровневый kernel32.LoadLibraryA через ctypes.WinDLL("kernel32"), что позволяет обойти блокировку
3. Ключевое исправление - загрузка DLL через системный API kernel32, а не напрямую через ctypes

Спасибо за внимание!
:catjam:
 
Назад
Сверху Снизу