понедельник, 25 февраля 2013 г.

Shim-ы и RT

С развитием эмулятора x86 Windows на Windows RT - практически каждый день сталкиваюсь с новыми багами в эмулируемых приложениях. Причем, причина некоторых "злостных" багов - не недостатки эмулятора, а кривость рук или природная лень авторов данных приложений.
То, что программы обращаются к блоку памяти после его освобождения или возвращают указатели на строки, выделенные на стеке - это еще мелочи. К выходу за пределы блока памяти  и к тому, что некоторые программы используют исключения Access Violation в своей нормальной работе вместо проверки параметров функций - я уже привык. Но вот некоторые конструкции заставляют переделывать большие участки существующего кода, просто чтобы заставить подобные программы хоть как-то работать. В итоге все-равно получается "не красиво", так как инече просто не реализуемо при использвоании имеющихся x86 движков (это я, например, про использование SuspendThread для синхронизации потоков). Так что вопрос о создании своего х86 движка, неуниверсального, но зато "заточенного" под конкретные нужды - давно решен утвердительно. Осталось только выделить на него время.

Чем больше занимаюсь проектом - тем больше начинаю уважать микрософт в плане поддержки старого софта на новых версиях Windows. И тем больше понимаю, что для осуществления запуска x86 программ на RT банального враппера поверх "родного" API и трансляции x86 команд будет недостаточно. В RT микрософт наконец выкинуло большие куски legacy кода, в некоторых случаях оставшегося еще со времен Windows 1.0, и реализация всех этих "костылей" теперь ложится на меня. Можно просто сравнить размер shim-ов в папке C:\Windows\AppPatch на RT и на настольной Windows 8. В релизе RT есть только несколько тестовых, в то время как в настольной - папка занимает более 10 мб. К счастью, формат базы shim-ов хоть и не документирован официально, но информации по нему предостаточно, так что можно "позаимствовать" данную базу в моем проекте.

По поводу application compatibility, и вообще по историческим апектам того, почему в windows некоторые вещи реализованы именно так, а не иначе - есть неплохой блог the old new thing. Его автор и книгу написал (найти ее скан не проблема), и выложил пару бесплатных глав. Одна из таких глав как раз посвящена историям про совместимость. И, читая данную книгу, я нахожу некоторые ошибки у себя. Как пример такой ошибки - вызов программой функции GetWindowLong(hwnd,DWL_DLGPROC) совершенно не означает, что hwnd == диалог, и программа хочет получить адрес его диалоговой процедуры. Ведь DWL_DLGPROC это просто константа 4, и в случае обычного окна - программа может хотеть прочитать второе слово из своих cbWndExtra, а храниться там может вообще все что угодно. Про это написано по приведенной выше ссылке в разделе "If it has eight bytes, it must be a dialog box".
Приходится определять класс окна (RealGetWindowClass) и смотреть диалог ли это. И только если диалог - добавлять спец обработку для эмуляции x86 диалоговых процедур.

5 комментариев:

  1. спасибо Вам за работу, очень полезное начинание! Подскажите пожалуйста, сделаете ли Вы адаптацию данной программы под какую-нибудь версию торрента? Сейчас при добавлении торрент-файла программа зависает

    ОтветитьУдалить
  2. mamaich, извините за вопрос не в тему. Не остались ли у вас исходники для qemu на андроид? Ссылки те что вы когда то выложили, не рабочие.

    ОтветитьУдалить
    Ответы
    1. Если и остались - то только на DVD болванках, которые засунуты неизвестно куда. Да и собирался он нетривиально - требовлася мой собственный порт GCC, сырцов от которого точно не сохранилось.
      То есть лучше его даже не искать.

      Удалить
  3. Спасибо вам за вашу работу. Пока не понял до конца как этим пользоваться. У вас никогда не возникало идеи поставить на рт другую ось убунту тач либо андроид?

    ОтветитьУдалить
  4. Поменял я свой VivoTab RT на Lenovo ThinkPad tablet 2 (еще и денег вернули), так что проект закрыт на неопределенное время.
    Исходники - в теме на xda-developers.

    А по вопросам - на асус можно было поставить любую другую ОСь, я нашел там как запускать неподписанные EFI модули, но асус закрыл эту дырку при обновлении UEFI для 8.1, причем закрыл топорно - из-за чего мне и пришлось сдавать планшет в сервис.
    К счастью, в сервисе инженеры не стали толком разбираться, и мои действия прокатили как гарантийный случай.

    ОтветитьУдалить