Eu tenho uma pasta com fotos antigas que coletei em zero. Eu transfiro de computador para computador com todos os meus arquivos a cada atualização, às vezes fico com saudade. Mas cada vez eu ficava um pouco envergonhado por o visualizador padrão do Windows 7 não mostrar animações GIF, embora minha memória me dissesse que nos tempos do XP a animação mostrava sem problemas. Com o próximo ataque de nostalgia, decidi iniciar o visualizador do XP no Windows 7. Depois de superar vários obstáculos, agora tenho certeza de que a animação GIF era realmente suportada lá! E o mais importante - agora eu posso assistir minha pasta antiga com fotos na interface autêntica do visualizador de imagens do Windows XP, o que cria uma atmosfera mais adequada =)
Download: shimgvw_xp32.7z (inclui o código binário e de origem do iniciador, além de shimgvw.dll do Windows XP SP3 em inglês).
Como isso foi feito?
O visualizador de imagens padrão no Windows XP não é um aplicativo comum. Ele está localizado na biblioteca shimgvw.dll e você não pode executá-lo diretamente - é necessário pelo menos
rundll32 (é necessário um caminho para um arquivo de imagem existente):
rundll32 c:\windows\system32\shimgvw.dll,ImageView_Fullscreen c:\test.gif
Mas esse truque não funciona ao tentar executar o shimgvw.dll no Windows XP no Windows 7 e posterior - o shimgvw.dll não pode ser carregado, ele precisa do modo de compatibilidade do Windows XP para funcionar corretamente. Isso pode ser conseguido definindo o modo de compatibilidade apropriado para a cópia do rundll32, mas a compatibilidade com o XP implica aumentar as permissões do aplicativo ao máximo, o que faz com que a caixa de diálogo do UAC apareça a cada inicialização, o que eu gostaria de evitar.
Uma pequena dança com um depurador tornou possível descobrir o motivo - durante o processo de inicialização, o shimgvw.dll subseqüentemente tenta importar várias funções do shunimpl.dll, onde funções obsoletas do shell são armazenadas, e o último se recusa a carregar por padrão se o ATOM "FailObsoleteShellAPIs" estiver ausente (a presença deste ATOM permite carregar a biblioteca , mas todas as funções obsoletas retornam o código de erro). O modo de compatibilidade com o XP, entre outras coisas, define esse ATOM, para que o visualizador inicie.
Foi decidido escrever um pequeno carregador que adiciona ATOM “FailObsoleteShellAPIs”, pergunta qual imagem abrir (se o caminho não foi especificado nos parâmetros) e transfere o controle para shimgvw.dll. O visualizador está funcionando bem (ou seja, a tarefa inicial foi concluída), então eu não investiguei quais funções obsoletas são importadas do shunimpl.dll e em quais casos elas são usadas - aparentemente, elas não fazem nada crítico para o visualizador funcionar.
Como para implementar o carregador, você não precisa de nada além de um pequeno número de funções WinAPI, decidi como um experimento criar um projeto usando o Clang sem usar um tempo de execução (anteriormente eu sempre usava o MSVC para essas danças). Assim, foi obtido um arquivo executável de tamanho de 14 kilobytes, dos quais 9 kilobytes foram para o ícone. Se alguém também gosta de criar gadgets sem dependências de bibliotecas não padrão, esse projeto pode servir como um pequeno exemplo de como isso é feito usando o Clang.