Подмена E-EDID на Windows
- вторник, 13 мая 2025 г. в 00:00:07
Все манипуляции с блоками E-EDID вы осуществляете только на свой страх и риск с полным пониманием того, какие манипуляции и с какой целью вы выполняете, так как блоки E-EDID могут содержать информацию о разности потенциалов уровней сигналов, подмена которой при использовании некорректно подобранного в качестве донора дампа E-EDID может привести к повреждению компонентов электрических цепей монитора.
Чуть более пяти лет тому назад, перед самым новым 2020 годом, освобождая комнату для проведения маленького новогоднего семейного торжества, мне пришлось отключить и убрать свой ПК. Литературными эпитетами не передать, каково было моё удивление, когда вскоре после новогодних торжеств мой комп вернулся на своё место, монитор, как и прежде, был подключён по DVI, но вместо привычной картинки 1920x1080@144Hz, мой старенький Full HD монитор BenQ XL2420Z уныло светился картинкой 1024x768@60Hz.
Покопавшись во всемирной паутине и собравшись с мыслями, пришёл к выводу, что проблема заключается в поврежденной информации блоков E-EDID, которую каждый уважающий себя видеовход монитора передаёт системе, и тогда возникла дилемма: либо поискать лишний носитель, поднять на нём Linux и использовать утилиты прошивки EEPROM через I2C, что за неимением достаточного опыта в данном вопросе могло повлечь ещё более негативные последствия; либо переключить монитор на DisplayPort, но на тот момент найти кабель с mini DP на DP — это квест не на один день (видяха располагала лишь тремя DVI и одним mini DP); либо попытаться настроить подмену блоков E-EDID в системе Windows, но всемирная паутина щедра лишь на информацию о подмене E-EDID на Linux, но не на Windows.
Для бывшего инженера техподдержки, много лет провозившегося с разными проблемами на операционной системе от Microsoft, эта ситуация была как брошенная в лицо перчатка, и уже было неважно сколько времени может уйти на поиски решения, в сравнении с решением квеста на добычу кабеля mini DP на DP.
Было бы странным, если популярная коммерческая операционная система от компании Microsoft не обладала элементарной возможностью подмены блоков E-EDID, и если в Linux задача решается указанием пути к файлу с двоичным образом дампа блоков E-EDID в соответствующем параметре строки аргументов загрузки ядра в настройках загрузчика GRUB2 и помещением двоичного образа в использующуюся при сборке загрузочного образа ядра структуру каталогов, то логично было предположить, что необходимую информацию о подмене блоков E-EDID при загрузке Windows удастся найти при изучении параметров команд bcdedit, но нет... Подсказка к решению была найдена при прочтении документа "Using an INF file to override EDIDs" раздела документации "Windows Display Driver Model". Оставалось лишь адаптировать полученную информацию к использованию в .REG-файле импорта/экспорта веток реестра Windows и найти подходящий дамп E-EDID.
Как уже упоминалось, блок E-EDID хранится в EEPROM монитора отдельно для каждого видеовхода и, помимо идентификационной информации, также содержит информацию о цветопередаче монитора, размерах видимого поля изображения и поддерживаемых разрешениях, как стандартных (VESA), так и собственных.
Выбранное разрешение, вкупе с размерами видимого поля изображения монитора, позволяет системе производить точный перерасчёт заданных типографскими пунктами размеров элементов интерфейса в пикселы и даже субпикселы, что важно не только для поддержки технологии WYSIWYG, но также для поддержки технологий, использующих субпиксельное сглаживание шрифтов, таких как "Microsoft ClearType". Подробнее о сглаживании шрифтов можно почитать в одной из статей журнала «КОД».
Итак... Подключения видеовходов монитора перечисляются в ключе реестра, путь к которому состоит из следующих фрагментов:
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\";
<VIDPID>
Узел, чьё наименование соответствует полю "Vendor/Product Identification" блока E-EDID (в некоторых источниках именуемый как "Plug and Play ID"), состоящее из трёхбуквенного идентификатора "Vendor Id" и шестнадцатеричного представления двух байт "Product Id";
<UID>
Уникальный идентификатор подключения видеовхода монитора к выходу видеокарты в системе;
Данный ключ реестра, помимо значений параметров подключения, содержит ключ "Device Parameters", который, в свою очередь, в значении "EDID" содержит копию первого блока E-EDID в шестнадцатеричном представлении (если этот блок удалось успешно считать).
Согласно описанию из "Using an INF file to override EDIDs", ключ реестра "Device Parameters" может содержать ключ "EDID_OVERRIDE" предназначенный для подмены некорректных 128-байтных блоков E-EDID. При этом, в ключе должны содержаться только те значения блоков E-EDID под своими индексами (начиная с "0"), которые требуют замены. Предполагается, что остальные — корректные 128-байтные блоки будут считаны системой, но это не наш случай. В первом блоке E-EDID также содержится количество последующих блоков. Таким образом, содержимое нашего .REG-файл будет выглядеть примерно так:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\<VIDPID>\<UID>\Device Parameters\EDID_OVERRIDE]
"0"=hex:00,FF,FF,FF,FF,FF,FF,00,...
В поиске подходящего дампа E-EDID мне помог репозиторий дампов проекта "Linux Hardware". Для подмены вручную достаточно экспортировать из реестра в .REG-файл соответствующую ветку реестра "Device Parameters" из ключа реестра, идентифицирующего подключение и, открыв полученный файл в простом текстовом редакторе, к примеру в «Блокноте» ("%SystemRoot%\system32\notepad.exe"), отредактировать его содержимое дополнив путь к ключу подмены "EDID_OVERRIDE" и заменив содержимое на проиндексированное содержимое 128-байтных блоков E-EDID, как продемонстрировано в примере выше. Хоть этот E-EDID будет содержать серийный номер чужого монитора, но нам гораздо важнее информация об экранных разрешениях и размерах видимого поля, а информацию о серийном номере мы можем не менять, пока у нас не дойдут руки до попытки восстановить эту информацию в EEPROM.
Но, согласитесь — делать всё это вручную как-то неспортивно для человека, который способен не только решать проблемы пользователей, но также может написать несколько строчек скрипта для командной оболочки "cmd" и несколько строчек JavaScript'а для Windows Script Host. В результате, из под моей клавиатуры появился маленький репозиторий WSH-скриптов, где в каталоге "edid" присутствуют интерактивные скрипты (можно запускать без аргументов командной строки), позволяющие частично автоматизировать процесс:
edid\edid_1stblock.cmd
Запускает на выполнение WSH-скрипт "edid\edid_1stblock.wsf", читающий из реестра и сохраняющий в двоичном формате дамп первого E-EDID блока. Данный скрипт может быть полезен для резервирования первого E-EDID блока, содержащего идентифицирующую ваш монитор информацию с другого — полностью рабочего видеовхода, на случай, если эта информация понадобиться вам для того, чтобы перенести её в соответствующий дамп E-EDID, который вы подготавливаете для восстановления повреждённых данных EEPROM;
edid\edid_dump2bin.cmd
Запускает на выполнение WSH-скрипт "edid\edid_dump2bin.wsf", преобразующий дамп E-EDID из текстового шестнадцатеричного представления в двоичный формат, который можно будет открыть в каком-нибудь редакторе дампов E-EDID или использовать в качестве источника информации для следующего скрипта;
edid\edid_override.cmd
Запускает на выполнение WSH-скрипт "edid\edid_override.wsf", создающий .REG-файл со всей необходимой для импорта в реестр информацией подмены E-EDID на основе информации о выбранном пользователем подключении видеовхода и файла с двоичным дампом E-EDID;
Все cmd-скрипты написаны таким образом, чтобы их можно было запускать по полному пути из любого рабочего каталога, который вы хотите использовать для сохранения информации.