Search notes:

Example DLL to demonstrate rundll32.exe

This is an attempt to demonstrate how a DLL can be created whose functions are called in a console (such as cmd.exe or PowerShell) via rundll32.exe).

EntryPoint

A (32-bit) function that can be called with rundll32.exe must be declared with stdcall calling convention. Apparently, this can be achieved with the CALLBACK macro:
void CALLBACK EntryPoint (HWND hWnd, HINSTANCE hInst, LPSTR  lpszCmdLine, int nCmdShow); // Windows 95 etc.
void CALLBACK EntryPointW(HWND hWnd, HINSTANCE hInst, LPWSTR lpszCmdLine, int nCmdShow); // Windows NT, 2K XP etc.
Under Windows NT and similar, rundll32.exe first tries to locate EntryPointW (using LPWSTR), then EntryPointA (using LPSTR) and then EntryPoint (again using LPSTR).

Source file

The following C source file exposes three functions: func_1, func_1W and func_2 according to the EntryPoint specification given above;
// cl /LD dll.c user32.lib /Fesome.dll /link /def:dll.def

#include <windows.h>


void CALLBACK func_1 (HWND hWnd, HINSTANCE hInst, LPSTR  lpszCmdLine, int nCmdShow) {
  MessageBoxA(0, lpszCmdLine, "func_1", 0);
}

void CALLBACK func_1W(HWND hWnd, HINSTANCE hInst, LPWSTR lpszCmdLine, int nCmdShow) {
  MessageBoxW(0, lpszCmdLine, L"func_1W", 0);
}

void CALLBACK func_2 (HWND hWnd, HINSTANCE hInst, LPSTR  lpszCmdLine, int nCmdShow) {
  MessageBoxA(0, lpszCmdLine, "func_2", 0);
}
Github repository Windows-development, path: /rundll32.exe/dll.c

.def file

If the source file is compiled with Microsoft's visual compiler, a .def file is needed:
LIBRARY some
EXPORTS
  func_1
  func_1W
  func_2
Github repository Windows-development, path: /rundll32.exe/dll.def

Compiling the source file

The source file is compiled into a DLL with
cl /LD dll.c user32.lib /Fesome.dll /link /def:dll.def

Calling the functions in the DLL

The functions in the DLL can now be called with rundll32.exe according to the syntax needed:
rundll32 some.dll,func_1 some arguments
rundll32 some.dll,func_2 other arguments

Using __declspec(dllexport)

When using __declspec(dllexport) on the function, a .def file is not required and the source code can also be compiled with GCC.
#include <windows.h>

extern __declspec (dllexport) void CALLBACK func (
   HWND      hwnd,         // handle to owner window
   HINSTANCE hinst,        // instance handle for the DLL
   LPTSTR    lpCmdLine,    // string the DLL will parse
   int       nCmdShow      // show state
)
{
   MessageBox(0, lpCmdLine, "func", 0);
}
Github repository Windows-development, path: /rundll32.exe/use-declspec.c
Compiling with Microsoft's visual compiler …
cl /LD use-declspec.c user32.lib /FeshowArguments.dll
… and with GCC:
gcc use-declspec.c -mwindows -shared -o showArguments.dll
After compiling, the function func can be called (as above) with
rundll32 showArguments,func foo bar baz
which creates this message box:

Thanks

Thanks to greatwolf who notified me of using the wrong calling convention in my example.

Index