Массовые музыкальные жанры XX века

       

Разгон... Sound Blaster'а


Крис Касперски


Статья была опубликована в журнале "Компьютер пресс"

Сказали бы мне некоторое время назад, что обычный Sound Blaster может наглым образом тормозить всю систему, я бы просто не поверил. Но… именно такой экземпляр Blaster'а мне попал недавно в руки. Причем, как показало небольшое расследование, это был дефект не конкретного экземпляра, а непосредственно самой модели, причем не одной, а сразу нескольких!

Изменением всего одного байта драйвера звуковой карты мне удалось значительно увеличить производительность системы, причем безо всякого ущерба для функциональности! О том, как был найден этот зловредный байт, и рассказывает настоящая статья.

...все началось с того, что я, заинтересовавшись новыми мультимедийными командами, решился-таки приобрести Pentium-III, поскольку мой старичок CELERON-300A их не поддерживал. Понятное дело, вместе с процессором потребовалось приобретать и новую материнскую плату, а поскольку на современных матерях ISA-слоты отсутствуют, пришлось менять звуковую карту Gold Edison на что-нибудь поновее. Выбор пал на Sound Blaster-128 PCI <CT 4830/PCI> от Creative (собственно, ничего более стоящего в магазине и не было).

Ничуть не стремясь к чудесам производительности (и на прежнем процессоре все буквально "летало"), я все же ожидал, что Pentium-III 733 будет, по крайней мере, не медленнее. А вот, как бы не так! Производительность системы после апгрейда существенно упала, и работа с ней превратилась в сплошное мучение. Постоянно используемые мною приложения Adobe Acrobat Reader и компьютерный словарь Lingvo выдерживали пяти-семи секундную паузу при загрузке (тогда, как прежде, они запускались практически мгновенно), такая же пауза наблюдалась у Microsoft Word и Microsoft Visual Studio при первом обращении к панелям инструментов и меню. Особенно замедлилась скорость открывания файлов в "Универсальном проигрывателе" – прежде выполняясь практически мгновенно, теперь она отнимала несколько секунд.


Перерыв все настойки BIOS, и, даже, переустановив операционную систему (Windows 2000 для справки), я не добился ровным счетом ничего, правда, выяснил, что на Windows 98 все работает отлично – ни задержек, ни тормозов там нет, и все приложения грузятся как из пушки: значительно быстрее, чем раньше. В конце туннеля замаячил свет: раз под Windows 98 система работает, значит, это не аппаратный, а программный глюк Windows 2000. Что ж, будем лечить!

Первым делом требовалось установить, – кто же вызывает задержку. Традиционно такие задачи решаются с помощью профилировщика, но, как назло, ни одного из них не оказалось под рукой, а бежать покупать диск среди глубокой ночи как-то не хотелось. На выручку пришел отладчик, интегрированный в Visual Studio (впрочем, подошел бы и любой другой, например Soft-Ice или Windeb).

Рассуждал я следующим образом: "раз и Word, и Visual Studio, и многие другие приложения при первом обращении к меню вызывают задержку, очевидно, виновники не они, а какой-то системный компонент, загружаемый ими. Если этот зловредный компонент автоматически загружается вместе с самим приложением, то пауза возникает при его запуске (как, например, в Adobe Acrobat Reader). А если же он загружается динамически – при возникновении в нем необходимости, – задержка появляется при обращении к меню".

Загрузив Word в отладчик и щелкнув мышкой по меню, я с удовлетворением отметил, что в окне "DEBUG" появились следующие строки:

Loaded 'C:\WINNT\system32\winmm.dll', no matching symbolic information found. Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information found. Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information found. Loaded 'C:\WINNT\system32\wdmaud.drv', no matching symbolic information found.



Ага! Все-таки что-то грузится! Остается только разобраться что… Заглянув в Platform SDK, я выяснил, что динамическая библиотека "winmm.dll" обеспечивает работу со звуком и мультимедиа, а, загрузив ее в HEX-редактор, быстро нашел текстовую строку "wdmaud.drv", красноречиво свидетельствующую о том, что драйвер "wdmaud.drv" грузит не кто иной, как "winmm.dll".



Логично, что "wdmaud.drv" предназначается для вывода звука, и это действительно так, поскольку его имя обнаружилось во вкладке "Драйвера" Sound Blaster'a в "Устройствах системы". Может ли Blaster или его драйвер вызывать тормоза? А почему бы и нет! Чтобы проверить это предположение я решился временно удалить "winmm.dll" из папки SYSTEM32. Но под Windows 2000 это сделать не так-то просто! Во-первых, winmm.dll уже используется системой и, стало быть, доступ к ней заблокирован даже для администраторов, а во-вторых, даже если ее и удалить, она все равно будет автоматически восстановлена операционной системой из резервной копии!

Чтобы воспрепятствовать этому, необходимо заблаговременно удалить winmm.dll из папки WINNT\system32\dllcache. А затем переименовать "winmm.dll" во что-нибудь другое, скажем "winmm.dl_". Весь фокус в том, что переименования используемых динамических библиотек система не запрещает, автоматически корректируя все активные ссылки, но после перезагрузки приложения будут по-прежнему пытаться загрузить именно "winmm.dll" (откуда же им знать о переименовании?!) и… не найдут ее! (Что мне, собственно, и нужно).

После удаления "winmm.dll" все тормоза мигом исчезли, но… вместе с ними исчез и звук, а, согласитесь, что за компьютер без звука! С другой стороны, приложениям наподобие Word, Visual Studio, Adobe Acrobat Reader звук совсем ни к чему (во всяком случае, у меня отключена озвучка пунктов меню и закрытия/открытия окон). Так почему бы не подсунуть им липовую "пустышку": динамическую библиотеку, имеющую то же самое имя, но не выполняющую никаких действий – просто возвращающую управление при вызове, а всем остальным приложениям (действительно нуждающимся в звуке) позволить обращаться к настоящей "winmm.dll"?

Сказано – сделано! Наскоро склепав dll'ку, не экспортирующую ни одной функции, я раскидал ее по всем каталогам, в которых находились исполняемые файлы Word, Visual Studio и других приложений.


Дело в том, что при загрузке динамических библиотек система сначала ищет их в каталоге приложения, и только если ее там нет, переходит к системному каталогу Windows.

C Word и Visual Studio этот фокус удался, а вот с Acrobat'ом не прошел – не понравилось ему, что в "пустышке" отсутствует функция "timeGetTime". Но трудно, что ль ее создать? (Тем более что ее прототип присутствует в SDK).

Наконец-то, с новым компьютером стало можно работать, а не мучаться, как раньше! Разве не прелесть – ни тормозов, ни задержек! Все буквально летает – не успеваешь щелкнуть по иконке, как приложение уже появляется на экране! Но подобный "грязный хак" не мог вызвать у меня должного удовлетворения. Ведь я не нашел причину глюка, а всего лишь загнал его поглубже внутрь.

И вот на Новый год, когда чудом выдалось несколько часов свободного времени, я решил взять врага если не штурмом, то осадой. Пошагово трассируя стартовую процедуру этой злощастной DLL, я искал функцию, вызывающую задержку, а, находя такую – перебирал все вложенные в нее функции одну за одной, а затем вложенные во вложенные... (В том, что тормоза вызвала именно стартовая процедура, у меня не было никаких сомнений, ибо задержка возникала именно при инициализации).

Через десяток минут я был вознагражден! Следы вели к функции OpenDriver, что выглядело логично, ибо наличие бага в штатной библиотеке "winmm.dll" производства Microsoft Corporation мне казалось сомнительным – она ведь одна на все карты, да и с прежним Blaster'ом работала без нареканий. Вот драйвер нового Blaster'а – дело другое! Нет ничего невероятного в том, что его инициализация (то бишь "открытие") происходит с задержкой. Круг "подозреваемых" сузился, но все же не было ясно, кто истинный виновник – непосредственно железяка или ее родной драйвер.

Пройдясь несколько раз дизассемблером по драйверу Blaster'a, я не нашел ничего, способного вызывать задержку, напротив, очень аккуратный и профессионально составленный код.


Выходит, все же железка?! Эх, если бы не Новый год, было бы можно вернуть ее продавцу с претензией на обмен… А вдруг не железка? Может мать? Теоретически мог иметь место конфликт с контроллером PCI-шины или просто кривой контроллер…

Продолжая копаться в недрах драйвера, я неожиданно заметил, что OpenDriver вызывается четырежды с последовательной инициализацией портов "wave", "midi", "mixer" и "aux", причем первые три инициализации пролетали на ура, а последняя-то и вызывала задержку.

Вот оно что! Виновата все же железка! AUX-порт на Blaster'е действительно был (хотя мною никак не использовался) и даже успешно функционировал, хотя до жути медленно инициализировался.

А зачем мне AUX-порт? Мне и обычных портов с лихвой хватает! Стоит ли ради него терпеть задержки?! В общем, я решил запретить драйверу инициализацию AUX'а (действительно, глупо инициализировать то, с чем все равно не работаешь). Конечно, правильнее всего было бы переписать код "winmm.dll", но… вносить исправления в двоичный файл чрезвычайно тяжело и весьма небезопасно. Поэтому я ограничился тем, что забил строку "AUX" нулями (в моей версии файла она расположена по адресу ".7752BB18"). Функция OpenDriver, получив на вход пустую строку, ничего не инициируя, просто возвращает управление.

Итак, что же конкретно должны сделать читатели, желающие устранить этот дефект у себя? (Если, конечно, у них он есть). Распишу все действия по шагам:


  • Шаг первый: зайдя в систему под именем (или с правами) администратора, переместите "winmm.dll" из каталога WINNT\system32\dllcache в какой-нибудь другой каталог, где вы храните резервные файлы. (Это на тот случай, если вы передумаете и захотите вернуть все на место)

  • Шаг второй: скопируйте WINNT\system32\winmm.dll в winmm.dl1 и откройте его в любом HEX-редакторе (например, Hiew'e, Qview'e или, на худой конец, в том, что встроен в популярную файловую оболочку DOS Navigator)

  • Шаг третий: в winmm.dll найдите строку "AUX", завершающуюся одним или несколькими нулями.


    Если эта та строка, которая вам действительно нужна, поблизости должны быть строки "Wave" и "Mixer" или "Midi" (в winmm.dll может быть несколько строк aux, использующихся различными ветвями программы)

  • Шаг четвертый: забейте строку "AUX" нулями (т.е. символами с кодом \x00, а не символами "0" с кодом \x30). Хотя на самом деле нулем достаточно затереть первую букву "A", но это будет не так аккуратно.

  • Шаг пятый: создайте командный файл следующего содержания: "ren WINNT\system32\winmm.dll WINNT\system32\winmm.dl_ & ren WINNT\system32\winmm.dl1 WINNT\system32\winmm.dll" и запустите его на выполнение.

  • Шаг шестой: перезагрузитесь.

  • Шаг седьмой: удалите WINNT\system32\winmm.dl_ и созданный вами командный файл.

  • Шаг восьмой: скопируйте измененную WINNT\system32\winmm.dll в папку WINNT\system32\dllcache




    <


    <


    <




    This Web server launched on February 24, 1997

    Copyright © 1997-2000 CIT, © 2001-2009 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...
    Советуем обратить внимание: кузовной ремонт лансер цена от опытной компании 77professional.ru.


    Содержание раздела