Есть у меня папка со старыми картинками, которые я собирал в нулевых. Переношу с компьютера на компьютер вместе со всеми моими файлами при каждом апгрейде, изредка захожу поностальгировать. Но каждый раз меня немного смущало то, что стандартный просмотрщик Windows 7 не показывал GIF-анимацию, хотя память мне подсказывала, что во времена XP анимация показывалась без проблем. При очередном приступе ностальгии я всё же решил запустить просмотрщик из XP на Windows 7. После преодоления ряда препятствий, я теперь уверен — GIF-анимация там действительно поддерживалась! А главное — теперь я могу смотреть свою старую папку с картинками в аутентичном интерфейсе просмотрщика картинок Windows XP, что создаёт более подходящую атмосферу =)
Скачать: shimgvw_xp32.zip (включает бинарник и исходный код лаунчера, плюс shimgvw.dll из англоязычной Windows XP SP3).
Как это работает?
Стандартный просмотрщик картинок в Windows XP — это не обычное приложение. Он находится в библиотеке shimgvw.dll, и запустить его напрямую нельзя — нужен как минимум rundll32 (указание пути к существующему файлу картинки обязательно):
rundll32 c:windowssystem32shimgvw.dll,ImageView_Fullscreen c:test.gif
Но этот трюк не срабатывает на Windows 7 и новее — shimgvw.dll не может загрузиться, ему для корректной работы нужен режим совместимости с Windows XP. Этого можно добиться, установив соответствующий режим совместимости для копии rundll32, но совместимость с XP подразумевает под собой повышение прав приложения до максимальных, что вызывает появление диалога UAC при каждом запуске, чего хотелось бы избежать.
Небольшой танец с отладчиком позволил выяснить причину — в процессе загрузки shimgvw.dll впоследствии пытается импортировать несколько функций из shunimpl.dll, где хранятся устаревшие функции оболочки, и последняя по умолчанию отказывается загружаться, если ATOM «FailObsoleteShellAPIs» отсутствует (наличие этого ATOM разрешает загрузку библиотеки, но тогда все устаревшие функции просто возвращают код с ошибкой). Режим совместимости с XP, помимо прочего, устанавливает этот ATOM, поэтому просмотрщик и запускается.
Было решено написать небольшой лоадер, который добавляет ATOM «FailObsoleteShellAPIs», спрашивает какую картинку открыть (если в параметрах не был передан путь), и дальше передаёт управление в shimgvw.dll. Просмотрщик работает нормально (т.е. изначальная задача была выполнена), так что я не стал исследовать, что же за устаревшие функции импортируются из shunimpl.dll и в каких случаях они используются — видимо, ничего критичного для работы просмотрщика они не делают.
Поскольку для реализации лоадера не нужно ничего кроме небольшого числа WinAPI функций, я решил в качестве эксперимента собрать проект при помощи Clang без использования рантайма (ранее я всегда использовал MSVC для таких танцев). Таким образом, получился исполняемый файл размером 14 килобайт, из которых 9 килобайт ушло на иконку. Если кому-то также нравится делать мини-приложения без зависимостей от нестандартных библиотек — данный проект может послужить небольшим примером, как это делается при помощи Clang.
Автор: VEG