С развитием эмулятора 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 диалоговых процедур.
То, что программы обращаются к блоку памяти после его освобождения или возвращают указатели на строки, выделенные на стеке - это еще мелочи. К выходу за пределы блока памяти и к тому, что некоторые программы используют исключения 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 диалоговых процедур.