INFO: Interfaces Rundll e Rundll32 do Windows

Sumário
O Microsoft Windows 95, Windows 98 e Windows Millennium Edition (Me) contêm dois programas utilitários da linha de comandos, com o nome Rundll.exe e Rundll32.exe, que permitem a invocação de uma função exportada de uma DLL, de 16 ou 32 bits. No entanto, os programas Rundll e Rundll32 não permitem chamar qualquer função exportada de qualquer DLL. Por exemplo, não é possível utilizar estes programas utilitários para invocar as chamadas da interface de programação de aplicações (API, Application Programming Interface) Win32 exportadas das DLLs do sistema. Os programas só permitem a chamada de funções de uma DLL que estejam explicitamente escritas para serem chamadas por esses programas. Este artigo fornece mais detalhes sobre a utilização dos programas Rundll e Rundll32 nos sistemas operativos Windows listados acima.

O Microsoft Windows NT 4.0, Windows 2000 e Windows XP são fornecidos apenas com Rundll32. Não há suporte para Rundll (o utilitário Win16) nestas plataformas.

Os programas utilitários Rundll e Rundll32 foram concebidos originalmente apenas para utilização interna da Microsoft. Mas as funcionalidades fornecidas pelos mesmos são de tal modo genéricas que, actualmente, os programas encontram-se disponíveis para utilização geral. Note que o Windows NT 4.0 é fornecido apenas com o programa utilitário Rundll32 e suporta apenas Rundll32.

Este artigo poderá conter hiperligações para conteúdo em inglês (ainda não traduzido).
Mais Informação

Rundll vs. Rundll32

Rundll carrega e executa DLLs de 16 bits, enquanto Rundll32 carrega e executa DLLs de 32 bits. Se passar o tipo incorrecto de DLL a Rundll ou Rundll32, esta poderá não ser executada sem que sejam apresentadas quaisquer mensagens de erro.

Linha de comandos de Rundll

A linha de comandos de Rundll será:
   RUNDLL.EXE <dllname>,<entrypoint> <optional arguments>				
Segue-se um exemplo:
   RUNDLL.EXE SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF				
O utilizador deverá considerar cuidadosamente 3 questões na linha de comandos mencionada acima:
  1. Rundll ou Rundll32 procuram o nome de ficheiro da DLL indicado nas localizações padrão (consulte a documentação relativa à função LoadLibrary() para obter detalhes). Recomenda-se que forneça um caminho completo para a DLL de modo a garantir que é localizada a DLL correcta. Para obter os melhores resultados, utilize o nome de ficheiro abreviado em vez do nome de ficheiro longo para garantir que não são apresentados caracteres ilegais. Repare que isto significa que uma DLL na pasta "C:\Programas" ("C:\Program Files") deverá ser convertida para o respectivo nome abreviado.
  2. O <nome_da_dll> não poderá conter quaisquer espaços, vírgulas ou aspas. Esta é uma limitação do analisador da linha de comandos de Rundll.
  3. Na linha de comandos mencionada acima, a vírgula (,) entre o <nome_da_dll> e o nome da função <ponto_de_entrada> é extremamente importante. Se a vírgula separadora não existir, a execução de Rundll ou Rundll32 falhará sem que sejam apresentadas quaisquer mensagens de erro. Além disso, não poderão existir espaços em branco entre o <nome_da_dll>, a vírgula e a função <ponto_de_entrada>.

Como funciona Rundll

Rundll executa os seguintes passos:
  1. Analisa a linha de comandos.
  2. Carrega a DLL especificada através de LoadLibrary().
  3. Obtém o endereço da função <ponto_de_entrada> através de GetProcAddress().
  4. Chama a função <ponto_de_entrada>, passando o fim da linha de comandos, que são os <argumentos opcionais>.
  5. Quando a função <ponto_de_entrada> termina, Rundll.exe descarrega a DLL e termina.

Como escrever a DLL

Na DLL, escreva a função <ponto_de_entrada> com o seguinte protótipo:

DLL de 16 bits:

  void FAR PASCAL __loadds  EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);				
DLL de 32 bits:
  void CALLBACK  EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);				
Mais uma vez, o utilizador deverá considerar 3 questões relativamente à função Ponto_De_Entrada:
  1. Obviamente, o nome "Ponto_De_Entrada" deverá ser substituído pelo nome real da sua função de ponto de entrada. Note que o ponto de entrada de Rundll32 não está relacionado com a função DllEntryPoint de uma DLL de 32 bits, que trata notificações de acções ligar/desligar de processos e threads.
  2. A função do ponto de entrada de Rundll32 tem de ser definida com a convenção de chamada _stdcall (CALLBACK utilizará o atributo _stdcall). Se o atributo _stdcall estiver em falta, a função utilizará a convenção de chamada _cdecl predefinida e, em seguida, Rundll32 terminará incorrectamente após a chamada da função.
  3. Uma vez que é necessário declarar a função com a convenção de chamada _stdcall do modo descrito anteriormente, o compilador de Visual C++ exportá-la-á como _EntryPoint@16 se a DLL estiver escrita em C ou utilizará outra decoração de nomes se a DLL estiver escrita em C++. Assim, certifique-se de que utiliza correctamente o nome exportado na linha de comandos de Rundll ou Rundll32. Se pretende evitar a utilização de nomes decorados, utilize um ficheiro .def e exporte a função do ponto de entrada pelo nome. Consulte a documentação do produto e o artigo que se segue para obter mais informações sobre decoração de nomes ao utilizar compiladores de Visual C++:
    140485 Exporting PASCAL-Like Symbols in 32-bit DLLs
Os parâmetros para o ponto de entrada de Rundll são os seguintes:
   hwnd - identificador de janela que deverá ser utilizado como a janela proprietária para          quaisquer janelas criadas pela DLL   hinst - o identificador da instância da sua DLL   lpszCmdLine - linha de comandos ASCIIZ que deverá ser analisada pela DLL   nCmdShow - descreve o modo de apresentação das janelas da DLL				
No exemplo que se segue:
     RUNDLL.EXE SETUPX.DLL,InstallHinfSection 132 C:\WINDOWS\INF\SHELL.INF				
Rundll chamaria a função de ponto de entrada InstallHinfSection() de Setupx.dll e passá-la-ia nos seguintes parâmetros:
   hwnd = (identificador da janela principal)   hinst = HINSTANCE de SETUPX.DLL   lpszCmdLine = "132 C:\WINDOWS\INF\SHELL.INF"   nCmdShow = (independentemente do nCmdShow passado a CreateProcess)				
Repare que é a função <ponto_de_entrada> (ou InstallHinfSection() no exemplo mencionado acima) que tem de analisar a respectiva linha de comandos (o parâmetro lpszCmdLine acima) e utilizar os parâmetros individuais conforme necessário. Rundll.exe analisa apenas até aos argumentos opcionais passados à respectiva linha de comandos. A análise restante compete à função <ponto_de_entrada>.

Notas especiais sobre diferenças entre o Windows 95 e o Windows NT

No Windows NT, Windows 2000 e Windows XP o comportamento de Rundll32.exe é ligeiramente diferente, de modo a suportar linhas de comandos UNICODE.

O Windows NT tenta primeiro GetProcAddress de <Ponto_De_Entrada>W. Se este ponto de entrada for localizado, pressupõe-se que o protótipo é:
   void CALLBACK   EntryPointW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine,               int nCmdShow);				
É exactamente o mesmo que Ponto_De_Entrada ANSI, à excepção de que o parâmetro lpszCmdLine é agora uma cadeia UNICODE.

Se o <Ponto_De_Entrada>W não for localizado, o Windows NT tentará GetProcAddress do <ponto_de_entrada>A e do <ponto_de_entrada>. Se um destes for localizado, será considerado um ponto de entrada ANSI e será tratado do mesmo modo que no Windows 95/98/Me. Assim, se pretender que a DLL seja executada no Windows 95 com suporte ANSI e no Windows NT/2000/XP com suporte UNICODE, deverá exportar duas funções: Ponto_De_EntradaW e Ponto_De_Entrada. No Windows NT/2000/Me, a função Ponto_De_EntradaW será chamada com uma linha de comandos UNICODE; no Windows 95/98/Me, a função Ponto_De_Entrada será chamada com uma linha de comandos ANSI.
Referências
Para obter um exemplo da utilização de Rundll, consulte o seguinte artigo sobre como iniciar uma aplicação do Painel de controlo no Windows 95 utilizando o utilitário da linha de comandos Rundll:
135068 HOWTO: Start a Control Panel Applet in Windows 95, 98, or WinNT
win95 tools
Propriedades

ID do Artigo: 164787 - Última Revisão: 01/24/2005 15:54:00 - Revisão: 4.2

  • Microsoft Win32 Application Programming Interface
  • kbinfo kbdll kbprogramming kbkernbase kbfaq kbusage KB164787
Esta informação foi útil?