AppCompat.

December 8th, 2009

Словечко «AppCompat», появившееся в моем лексиконе за время работы над Wow64, обозначает множество вещей. Чаще всего – геморрой. Иногда – великий геморрой. Происходит оно от «application compatibility» – т.е. совместимость OS с приложениями, она же – «обратная совместимость».

Почему геморрой? Да потому, что эта совместимость, – она только для пользователей операционной системы полезна. Для разработчика OS эта совместимость хуже вреда. Скажем, исправляете вы ошибку в обработке некорректных параметров той или иной функции Win32. Как вы думаете, что случится после того, как исправление пройдёт все тесты и будет послано в репозиторий кода? Через пару недель-месяцев с вероятностью сильно отличной от нуля вы получите письмо от Gov Maharaj, что это исправление ломает то или иное приложение. Или хуже – ломает некую библиотеку, которой пользуется множество приложений. Да, это приложение сует непонятно что в параметры этой функции. Да, оно никогда не должно было работать. Но работало – значит будь добр, исправь. Бывает, конечно, и наоборот, OS делает непонятно что, и приложения работали просто чудом.

Я тут собрал небольшую коллекцию багов, найденных примерно вышеописанным образом в процессе работы над Windows 7:

  1. Некий софт вызывал функцию RegEnableReflectionKey в ситуации, когда она не делала ничего, просто возвращая ERROR_SUCCESS. Собственно говоря, она и не могла ничего сделать, даже если бы попыталась. Софт, тем не менее, тщательно проверял код возврата и отказывался работать в случае, если функция возвращала ошибку.
  2. Некий антивирус поломался, когда в один прекрасный момент изменился регистр букв в имени ключа «HKEY_LOCAL_MACHINE\Software\Wow6432Node». Пришлось вернуть прежнее начертание.
  3. Оригинальная версия механизма Registry Value Redirection (замена «%ProgramFiles%» на «%ProgramFiles(x86)%») использовала чувствительное к регистру сравнение строк. Когда это было замечено и исправлено выяснилось, что несколько разных приложений используют строки другого регистра и, тем самым, обходят перенаправление. И как только перенаправление заработало «как положено» все очень сильно поломалось.
  4. Некий софт указывал оба флага KEY_WOW64_32KEY и KEY_WOW64_64KEY при вызове RegCreateKeyEx. Зачем и почему – не понятно. Но программа очень обиделась, когда функция начала возвращать ошибку. К счастью, в этом случае было проще исправить само приложение.
  5. В один не столь прекрасный момент, выяснилось, что функции RegCeateKeyEx и RegOpenKeyEx по разному реагируют на ведущий слеш в имени ключа. В зависимости от версии OS, разрядности приложения, комбинации флагов KEY_WOW64_XXX и ветки реестра, где создавался ключ, можно было получить разный результат. К сожалению, к моменту, когда это было обнаружено, было уже поздно что-либо менять в коде реестра.
  6. Обнаружилось, что создатели некоторых программ изобретательно подошли к регистрации COM объектов в реестре во время инсталляции. COM объекты регистрируются в «HKEY_CLASSES_ROOT\CLSID». Этот ключ «перенаправляется» в Wow64, т.е. существуют две версии этого ключа 32-х и 64-х разрядная, которые синхронизируются между собой с помощью механизма Registry Reflection. Так вот, содержимое некоторых из ключей создавалось по кусочкам, скажем «LocalServer32» брался из .msi и клался в 32-х битный ключ, а «ProgID» дописывался позднее из Custom Action в 64-х разрядный ключ. Это худо-бедно работало, пока из Windows 7 с корнем не выкорчевали Registry Reflection.
  7. Однажды мне пришел баг, который был вызван тем, что строка, передаваемая в другой компонент Windows в формате UNICODE_STRING, не завершалась нулем. Но позвольте, заметил я, UNICODE_STRING и не должен завершаться нулем! Но ведь раньше этот конкретный UNICODE_STRING завершался нулем, резонно возразили владельцы компонента. Пришлось вернуть ноль на место.

Самое неприятное свойство подобных ошибок заключается в том, что исправлять приходится как раз «правильный» код. «Неправильный» код либо невозможно исправить (код уже выпущен, приложение не наше, разумного способа обновить инсталляции на дисках пользователей нет), либо сложнее исправить (например, этот код имеет гораздо больше зависимостей, которые нельзя протестировать в разумные сроки).

Вот так и живем…

, ,

  1. Vokinneberg
    December 8th, 2009 at 10:17 | #1

    Очень познавательно, спасибо! Интересно отметить что большинство ошибок возникает из-за проблем работы с реестром. А так же отчасти становится понятно, почему винда порой бывает не стабильна. Хотя судя по последним версиям становится очевидно что был проведет титанический труд по стабилизации.

  2. December 8th, 2009 at 10:29 | #2

    Vokinneberg :
    Интересно отметить что большинство ошибок возникает из-за проблем работы с реестром.

    Это просто просто проект, над которым я работал, весь и состоял в изменении функциональности реестра. Соответственно и ошибки все про реестр.

  3. vkni
    December 8th, 2009 at 21:19 | #3

    А как народ “правильно” работает с реестром, с помощью каких инструментов?

    Вот, к примеру, беру я конфигурационный файл Windows ini или UNIX и редактирую его используя всю мощь современных текстовых редакторов – поиск с рег. выражением, замена, замена в определённой области и т.д.

    В стандартном regedit этого нет. Поэтому, если программа сохраняет, к примеру, какой-то набор абсолютных путей, и они все переехали с диска на диск, приходится в реестре их менять вручную “брутально и беспощадно”.

  4. Gop
    December 8th, 2009 at 21:30 | #4

    Ну и поделие – этот реестр.

  5. Sergey
    December 9th, 2009 at 02:20 | #5

    Не очень понятно, вы все эти изменения делаете для существующей системы или для будущей? Если для уже вышедшей, то претензии в какой-то мере справедливы. Если для след, то почему вас это волнует?

  6. December 9th, 2009 at 07:52 | #6

    vkni :
    А как народ “правильно” работает с реестром, с помощью каких инструментов?

    Реестр – это фактически база данных. Для работы с ним используются аналогичные инструменты. Хочеться редактировать содержимое в обычном редакторе – экспортируется .reg (по аналогии с .sql), редактируется и импортируется обратно. Хочеться выполнить запрос из коммандной строки – есть reg.exe. Хочеться посмотреть на структуру базы глазами – есть regedit.exe.

    Редактировать реестр напрямую с удобствами “как в текстовом редакторе” нельзя примерно по тем же причинам, почему этого не делают с базами данных.

    Gop :
    Ну и поделие – этот реестр.

    Агрументы?

    Sergey :
    Не очень понятно, вы все эти изменения делаете для существующей системы или для будущей? Если для уже вышедшей, то претензии в какой-то мере справедливы. Если для след, то почему вас это волнует?

    Это делается и для выпущенных и для будущих версий системы. Windows 7 тогда была “будущей” версией. Делается это для того, чтобы существующие приложения продолжали работать как ни в чем не бывало. Пользователям все равно, кто виноват в том, что их приложения не работают на следующей версии Windows. Более того, даже если создатель приложения активно его поддерживает и выпустил новую версию совершенно бесплатно, только скачай и установи, пользователи не стремяться обновлять приложения. В результате мы пытаемся сделать систему насколько это возможно совместимой с существующим софтом.

  7. vkni
    December 9th, 2009 at 08:46 | #7

    Алексей Пахунов :
    Редактировать реестр напрямую с удобствами “как в текстовом редакторе” нельзя примерно по тем же причинам, почему этого не делают с базами данных.

    Ну почему же совсем нельзя? Это же не просто абстрактная БД, а БД с чётко определёнными полями и их типами – int, string, bin. С довольно чёткой иерархической структурой. К сожалению, без возможности комментариев, которые бы очень пригодились.

    Опять-таки, вы пишете про “экспортировать в txt”, а потом редактировать. Можно же было в regedit сделать и поиск по рег. выражению, и удобный автоматический “экспорт” и “импорт” подветки в отдельное текстовое окно.

  8. tony
    December 9th, 2009 at 11:07 | #8

    Мдя. Интересный пост. Спасибо.

  9. December 9th, 2009 at 11:28 | #9

    vkni :
    Это же не просто абстрактная БД, а БД с чётко определёнными полями и их типами – int, string, bin. С довольно чёткой иерархической структурой. К сожалению, без возможности комментариев, которые бы очень пригодились.

    Точно также, как и обычная база данных. Типы, структура таблиц, взаимоотношения и т.п. – все четко определено.

    vkni :
    Опять-таки, вы пишете про “экспортировать в txt”, а потом редактировать. Можно же было в regedit сделать и поиск по рег. выражению, и удобный автоматический “экспорт” и “импорт” подветки в отдельное текстовое окно.

    Можно, конечно. Я не говорю о технической невозможности это сделать. Это можно сделать и, по всей видимости, многочисленные заменители regedit пытаются делать что-то похожее. Я привел в пример базы данных, потому как для них подобная возможность (редактирование как текст) также не реализована, хотя никаких технических проблем с этим нет.

  10. TEH3OP
    December 9th, 2009 at 23:39 | #10

    Всплакнул… и сам в подобном постоянно пачкаюсь. Проблема (надеюсь что только почти) всех старых проектов в том что надо постоянно прогибаться под “старый” кривой код. А при словах “старых” программистов: “Не знаю, у меня всё работает…”, – хочется уже стукнуть больно!
    C UNICODE_STRING правы вы, IMHO. Разработчики стороннего COM должны ещё спасибо сказать за найденый баг. :)

    vkni :
    Можно же было в regedit сделать и поиск по рег. выражению, и удобный автоматический “экспорт” и “импорт” подветки в отдельное текстовое окно.

    Есть много разнообразных инструментов для работы с реестром, с поиском чуть-ли не по китайским иероглифам. С ini-файлом, кстати, тоже множество ошибок возникает.

  11. Dmitry
    December 11th, 2009 at 13:01 | #11

    Вот я видел уже миллион, наверное, постов про то, как героически команда windows борется с косяками всяких Мажараджи. С другой стороны, так как разработчики под макось в моем кругу тоже не редкость, литры слез были вылиты по поводу смены номера 10.7 на 10.8, считай что викли-билд свежий выложили. А в винде некоторые “апп-компат фишки” живут уже лет двадцать, насколько я знаю.

    Так вот вопрос: а почему, собственно, нельзя оставить ту же более менее удачную ХР в продаже и поддержке, еще лет на десять. И написать семерку уже без оглядки на глючный кривой софт, тем более твикеры и антивирусы?

  12. December 11th, 2009 at 15:02 | #12

    Dmitry :
    Так вот вопрос: а почему, собственно, нельзя оставить ту же более менее удачную ХР в продаже и поддержке, еще лет на десять. И написать семерку уже без оглядки на глючный кривой софт, тем более твикеры и антивирусы?

    Ну представьте, вышла Windows 7: драйверов нет, приложения не работают, разработчики софта клятвенно обещают в течении пары лет все исправить. Vista покажеться раем и манной небесной одновременно.

  1. No trackbacks yet.
Comments are closed.