DllMain in Freebasic - DllEntryPoint


Freebasic is a free and open-source self hosting compiler. It can produce fast and efficient pure native code for all Versions of Microsoft Windows and Linux Operating System. In this post, I am going to show you how to write a standard DLL in Freebasic. Of course, the -dll switch is all that you need to pass to get a working DLL but, you will have to manually work a bit if you need to add the DllMain in Freebasic DLL.

The Barebone of a DLL Code in C Programming Language looks something like this:
/*    mtsDll.C    */

#include

BOOL WINAPI DllMain ( HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved )
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        MessageBox(NULL, "DLL Mapped into Memory", "Caption", MB_OK);
    }
    else if (fdwReason == DLL_PROPCESS_DETACH)
    {
        MessageBox(NULL, "DLL UnMapped from Memory", "Caption", MB_OK);
    }
return TRUE;
}
If it is C++, you will need to add extern "C" just before BOOL. But, even if you enter your own DllMain in Freebasic DLL, which looks something like this:
/'    mtsDll.BAS    '/

#include "windows.bi"

Function DllMain stdcall Alias "MAIN" ( hInstDll As HINSTANCE, _
          fdwReason As DWORD, lpvReserved As LPVOID ) As BOOL Export                             
    if (fdwReason = DLL_PROCESS_ATTACH) then
            MessageBox(NULL, "DLL Mapped into Memory", "CAPTION", MB_OK)
    ElseIf (fdwReason = DLL_PROCESS_DETACH) then
            MessageBox(NULL, "DLL UnMapped from Memory", "CAPTION", MB_OK)
    EndIf
return TRUE
End Function
Calling the Freebasic Compiler (FBC.EXE) with the -dll switch, you can create your own DLL like this:
    fbc mtsDll.bas -export -dll 


Please note that we have added our own DllMain in the DLL SourceFile. Now after calling our DLL with RUNDLL or LoadLibrary, we should have our DLL popping up a MessageBox just as written in the Code.


But, you will not have the Code in the DllMain performed. This is because the Freebasic Compiler redirects the DLL Entrypoint by default to it's own copy of DllMain (defaults it) (which ofcourse, doesnot contain the Code you have written).



To counter with this problem, we have to pass some switches to the Linker in the Freebasic Development Package (BIN/WIN32/LD.EXE) by the -Wl switch. So, lets re-compile our DLL, this time with a modified switch to the Freebasic Compiler (FBC.EXE):
    fbc mtsDll.bas -export -dll -Wl " -e _MAIN@12"

Calling FBC with -Wl switch
When we use the -Wl switch the Freebasic Compiler passes the command inside the double quotes (") to the Linker (BIN/WIN32/LD.EXE) thus, making our DllMain the default Entrypoint of the DLL. The -e switch tells the Linker that the Entrypoint is to be MAIN (which ofcourse is the Alias of DllMain). Please note that it is '_MAIN' and not 'MAIN'.

So, after compiling the DLL, lets call it with RUNDLL like so:

DLL_PROCESS_ATTACH
DLL_PROCESS_DETACH
And voila, we have our MessageBox popping up. DllMain is important where we need to initialize and or de-initialize the Code before proceeding | exiting from the DLL's internal / exported functions ( usually for: memory initialization / cleanup ). But, there are many serious restrictions about what you can do with the DLLMain. Even careless call(s) to other DLLs not loaded in the DLL's memory will lead to the DLL crashing while others can lead to a situation called DLL Deadlock. By default, only the Kernel32.DLL is present in the DLL's memory, by using the functions exported by the Kernel32, you can load other important DLLs like User32 and perform your activities.

And, we can see from DLL Export Viewer that MAIN is the exported function (and our Dll's Entry Point):

DllExportViewer - mtsDll.dll

Found this post useful ? If so, Click +1 and RECOMMEND THIS SITE on Google

2 comments:

  1. Thanks for that, it is useful to know, for me.
    Tip - You do fbc a dis-service with your example... it looks long-winded compared to the C version, but need not be so:-

    /' mtsDll.BAS '/

    #include "windows.bi"

    Function DllMain stdcall Alias "MAIN" ( hInstDll As HINSTANCE, _
    fdwReason As DWORD, lpvReserved As LPVOID ) As BOOL Export
    if fdwReason = DLL_PROCESS_ATTACH _
    MessageBox(NULL, "DLL Mapped into Memory", "CAPTION", MB_OK)
    ElseIf fdwReason = DLL_PROCESS_DETACH _
    MessageBox(NULL, "DLL UnMapped from Memory", "CAPTION", MB_OK)
    EndIf

    return TRUE
    End Function

    ReplyDelete
  2. A DIS-Service? you must be kidding me.
    The C Version looks cool because of the core features of the language itself. This is just a direct C to Basic Translation and my sole intention was to show the switches that need to be passed to use own custom DLL Entry point and not to show it's translation to be judged by it's look and/or length.

    Anyway thank you for the tip.

    ReplyDelete