Недокументированные функции (oh, so tasty) — их любят в Microsoft больше всего. Попробуем чрез комментарии заглянуть в головы тех, кто непосредственно пишет Windows, чтобы понять главное: отчего в этой компании откровенный баг через какое-то время вдруг превращается в фичу.
Продолжение рассказа (вторая часть) начатого вот здесь.
Отдельная тема — это поддержка ошибок поддержки других ошибок, особенно, когда ошибка в поддержки другой ошибки допускается в известных продуктах третьих фирм, и в результате Microsoft вынуждена обеспечивать работоспособность подобных ошибок и в следующих версиях (что превращает её уже в фичу), даже когда всё было найдено и исправлено позже. Если вы ничего не поняли из написанного — не пугайтесь, это просто неизбежные издержки любой БОЛЬШОЙ разработки, просто расслабьтесь и забудьте о том, что ранее читали в умных книгах.
Очень показательный случай вышеописанного, подробно изложенный в комментарии в исходниках Windows, это поддержка некоторых продуктов от Borland, в частности JBuilder Professional. Ниже описана реализация взаимодействия с особенностями компилятора Borland, который весьма своеобразно обрабатывает ошибку в MS Windows с помощью подхода «brute force», которая впоследствии была всё-таки исправлена в MS, и поэтому теперь необходимо насущно решить новую проблему... эээ, ну как бы её эмуляции, чтобы всё работало, как работало и прежде.
Взято из filenew.cpp ////////////////////////////////////////////////////////////////////////// // // CFileOpenBrowser::ResetDialogHeight // // ------------------------------------------------- // These guys relied on a bug in Win95/NT4's Comdlg32 that we fixed in IE4. // So instead of reintroducing the bug, we detect that they are relying // on the bug and hack around their stupidity. // // These guys do a SetWindowLong(GWL_STYLE) on the dialog box and // then reparent it! Unfortunately, they didn't quite get their // bookkeeping right: They forgot to do a RedrawWindow after removing // the WS_CAPTION style. You see, just editing the style doesn't do // anything - the style changes don't take effect until the next // RedrawWindow. When they scratched their heads ("Hey, why is // the caption still there?"), they decided to brute-force the // solution: They slide the window so the caption goes "off the screen". // // Problem: We fixed a bug for IE4 where ResetDialogHeight would screw // up and not resize the dialog when it should've, if the app did a // SetWindowPos on the window to change its vertical position downward // by more than the amount we needed to grow. // // So now when we resize it properly, this generates an internal // RedrawWindow, which means that Borland's brute-force hack tries // to fix a problem that no longer exists! // // Therefore, ResetDialogHeight now checks if the app has // // 1. Changed the dialog window style, // 2. Moved the dialog downward by more than we needed to grow, // 3. Forgotten to call RedrawWindow. // // If so, then we temporarily restore the original dialog window style, // do the (correct) resize, then restore the window style. Reverting // the window style means that all the non-client stuff retains its old // (incorrect, but what the app is expecting) size. // //////////////////////////////////////////////////////////////////////////
Второе интересное направление всех этих замысловатых для внешнего наблюдателя «хаков на базе других хаков» — это активное использование недокументированных особенностей, как в других продуктах, так и в самой Windows, что как видно ниже, иногда приводит к аналогичным шаблонным ситуациям:
«для поддержки старого недокументированного вызова API, который уже не существует, создадим обёртку-переходник для его эмуляции на базе нового недокументированного вызова, дабы всё продолжало работать и далее».
Что будет со всем этим, когда со временем исчезнет и «новый недокументированный API-вызов»? Спросите об этом того, кто написал всё это (если он уже не вышел на пенсию).
Цитата из файла: private\mvdm\wow32\wcntl32.c: // These undocumented messages are used by Excel 5.0 Цитата из файла: private\mvdm\wow32\wgdi31.c: // InquireVisRgn is an undocumented Win 3.1 API. This code has been // suggested by ChuckWh. If this does not fix the s 2.0 // problem, then ChuckWh would be providing us with an private entry // point. Цитата из файла: private\mvdm\wow32\wgfont.c: * This thunk implements the undocumented Win3.0 and Win3.1 API * GetCurLogFont (GDI.411). Symantec QA4.0 uses it. * To implement this undocumented API we will use the NT undocumented API
В некоторых случаях, читая подобные комментарии видно, как сами разработчики пугаются как малые дети некоторых следствий из подобных ранее непродуманных решений, с которыми им пришлось неожиданно столкнуться через какое-то время. Иногда они философски озадачены этим, а иногда просто в бешенстве, приведу лишь пару примеров этого:
Цитата из файла: private\ntos\w32\ntuser\kernel\mnpopup.c: // Set the GlobalPopupMenu variable so that EndMenu works for popupmenus so // that WinWart II people can continue to abuse undocumented functions. Цитата из файла: private\windows\shell\accesory\hypertrm\emu\minitel.c: // Guess what? Latent background color is always adopted for mosaics. // This is a major undocumented find... Цитата из файла: private\windows\shell\accesory\hypertrm\emu\minitelf.c: // Ah, the life of the undocumented. The documentation says // that this guys does not validate, colors, act as a delimiter // and fills with spaces. Wrong. It does validate the color. // As such its a delimiter. If...
Союз «If» обрывается здесь глубокомысленным многоточием, теперь мы так никогда и не узнаем, к чему всё это может привести... По всему видно, что с этими исходниками работает множество людей, поэтому они активно комментируют друг друга, иногда восхищенно записывают свои диковинные находки найденные в чужом коде, то, что их лично зацепило. Иногда эта какофония из разных голосов напоминает своего рода шизофрению, в исходниках Windows также можно найти много мест, где некий программист задает в зияющую пустоту свои вопросы, терпеливо и с надеждой вопрошая, как правило, это типичное unde malum «ну почему же всё устроено именно так?».
В полном согласии с жанром, большинство подобных вопросов остаются без ответа, впрочем, изредка видны куцые комментарии-ответы в стиле stackoverflow.com, которые по смыслу были дописаны какое-то время спустя — это откликнулся коллега, дабы внести недостающую ясность тому, кто последует по стопам этой дискуссии. Нагромождения из текстов-комментариев в виде множества версий-догадок иногда имеют протяженность в два-три экрана, что смахивает скорее на хроники, чем на документ с кодом большой программы.
Исходный код подобной большой системы — как живой организм, это большой муравейник. Он слишком большой и разнородный, чтобы требовать от него какую-то четкую систему, которой следовали бы все разработчики без исключения — все комментария оформляются по-разному, здесь нет никакой единой системы и в помине: в них встречаются равно как благословления, остроумные имена переменных, так и личные проклятия в адрес своих заклятых недругов.
Кстати, лично мои субъективные впечатления от быстрого просмотра кода этой системы очень даже неплохие. По крайней мере к Microsoft’у у меня всегда было своё личное предубеждение, сформированное ещё ранее, когда у меня была возможность увидеть исходники некоторых её других продуктов рангом поменьше, которые надо сразу признать, из-за недостатка времени я просматривал примерно также, как и сегодня рассмотренные — вообщем-то, что называется «по диагонали».
Но тогда даже такого беглого просмотра было достаточно, чтобы понять, как своеобразно соблюдаются «coding guidelines» в Microsoft, в продуктах которой некоторые методы могут содержать тело из кода в сотню экранов, а сам файл с их исходником — «весить» больше мегабайта. В коде Windows 2000 нет этого и в помине, и хотя потроха этой Винды и производят впечатление гигантского и многосложного механизма, пронизанного тончайшими капиллярами смысла, безумная сложность аккуратно расфасована по файлам, содержащих не только холодную логику кода, но и множество чисто человеческого навеса, в котором комментирует, рефлексирует, болезненно обвиняя себя и других, часто заочно оппонируя своим коллегам, а порой просто шутит, в том числе, применяя пикантные названия для констант и переменных, всё тот же маленький человек, который таким образом находит способ хоть как-то заявить о себе, не обязательно со злым умыслом, как это привиделось горячим финским (и не только) последователям Linux-религии.
И напоследок предлагаю вам взглянуть на фрагмент исходников от Windows Vista, который опубликовал 1 апреля журнал PC World, надо признаться, что тут есть над чем задуматься:
1 комментарий
Предложение задуматься над достаточно плоской первоапрельской шуткой убило.