Thursday, November 22, 2012

How do I forward an exported function to an ordinal in another DLL?

The syntax for specifying that requests to import a function from your DLL should be forwarded to another DLL is

; A.DEF
EXPORTS
 Dial = B.Call
This says that if somebody tries to call Dial() from A.DLL, they are really calling Call() in B.DLL. This forwarding is done in the loader. Normally, when a client links to the function A!Dial, the loader says, "Okay, let me get the address of the Dial function in A.DLL and store it into the __imp__Dial variable." It's the logical equivalent of

client::__imp__Dial = GetProcAddress(hinstA, "Dial");
When you use a forwarder, the loader sees the forwarder entry and says, "Whoa, I'm not actually supposed to get the function from A.DLL at all! I'm supposed to get the function Call from B.DLL!" So it loads B.DLL and gets the function Call from it.

hinstB = LoadLibrary("B.DLL");
client::__imp__Dial = GetProcAddress(B, "Call");
(Of course, the loader doesn't actually do it this way, but this is a good way of thinking about it.)

But what if the function Call was exported by ordinal? How do you tell the linker, "Please create a forwarder entry for Dial that forwards to function 42 in B.DLL?"

I didn't know, but I was able to guess.

Back in the days of 16-bit Windows, there were two ways to obtain the address of a function exported by ordinal. The first way is the way most people are familiar with:

FARPROC fp = GetProcAddress(hinst, MAKEINTRESOURCE(42));
The second way uses an alternate formulation, passing the desired ordinal as a string prefixed with the number-sign:

FARPROC fp = GetProcAddress(hinst, "#42");

Read more: The old new thing

Posted via email from Jasper-Net