суббота, 4 декабря 2010 г.

Двойное тайное ANSI, часть 2 (самая кривая часть, извините!)

Это перевод Double Secret ANSI, part 2 (the brokenest one yet, sorry 'bout that!). Автор: Майкл Каплан.

Итак, когда я первый раз написал о двойном тайном ANSI, я был лишь немного удивлён, когда увидел, что постоянный читатель Mihai знал, к чему я веду...

(Mihai работает на компанию, которая разрабатывает некоторые из таких приложений с поддержкой двойного тайного ANSI, о которых я говорил!)

Видите-ли, мы вроде как сломали некоторые из таких приложений в Vista.

Я немного придержал этот пост, потому что я хотел узнать сначала, какие у нас планы по этому вопросу. А Shawn только что опубликовал пост о том, что некоторые клавиатуры не работают в ANSI приложениях в Windows Vista RTM, и о том, как планируется это исправить.

Это всё клёво, и я уверен, что мы оба опубликуем пост, когда исправление будет готово. Это довольно плохой баг.

Как появился этот баг - это довольно интересно, так что я поговорю немного об этом...

Видите ли, к моменту, когда загружается клавиатурная раскладка, клавиатурный код режима ядра вызывает функцию, которая использует TranslateCharsetInfo и LANGID, который сидит внутри KLID (Keyboard Layout Identifier) клавиатуры. Он получает часть lsCsbDefault записи TLocaleSignature и использует её для трёх целей:
  • Чтобы решить, передавать ли INPUTLANGCHANGE_SYSCHARSET в параметре WPARAM уведомления WM_INPUTLANGCHANGEREQUEST1;
  • Чтобы выбрать, что пойдёт в параметр WPARAM уведомления WM_INPUTLANGCHANGE;
  • Чтобы иметь кодовую страницу, которую можно использовать для всех ANSI/Unicode преобразований, которые нужны не Unicode приложениям.
Вот из этого последнего пункта и идёт сила этих двойных тайных ANSI приложений :-)

И он же - этот баг в нескольких записях TLocaleSignature в Vista, который привёл к проблемам в этих же приложениях :-(

Это не значит, что аналогичные баги в данных TLocaleSignature не существовали раньше.

Потому что они были. Помните этот пост?

Просто в этот раз в Vista значения оказались сломаны сильнее. Упомянул ли я, что мы уже работаем над исправлением?

Хотя, чтобы быть честным, в будущих версиях я собираюсь исследовать, нельзя ли упростить немного эту работу. Я имею ввиду, что вместо того, чтобы иметь переходник user/kernel mode для пользовательского режима, чтобы вызывать gdi32.dll, которая может вызвать kernel32.dll, чтобы получить то, что и так было загружено в режим ядра, чтобы получить то, что было (говоря исторически) единственным наименее надёжным кусочком в данных локали, что мы поставляем - можно просто удалить несколько связей, которые просто не нужны.

Вот и говори после этого о ненужных зависимостях!

Особенно, если вы учтёте тот факт, что вообще получить кодовую страницу, которая используется клавиатурным кодом в любой более поздний момент времени, невероятно трудно. Я имею ввиду, что же делать честному double+ ANSI приложению? :-)

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

Лишь слегка обнадеживающим моментом здесь является то, что большинство приложений, не поддерживающих Unicode, не делают много больше, чем простая поддержка единственной кодовой страницы системы по умолчанию.

Для всех тех, кто пишет double+ ANSI приложения - извините! Это не был хитрый план, чтобы заставить всех перейти на Unicode.

Прим.пер.: вот статья KB с исправлением. Кроме того, это исправление вошло в SP1 для Vista.

1 - Дальнейшее обсуждение странностей c этими уведомлениями.

This post brought to you by А (U+0410, a.k.a. CYRILLIC CAPITAL LETTER A)

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.