• [OT?] Borlands Tasm32 syntax for calling a function in a specific DLL.

    From R.Wieser@address@nospicedham.not.available to comp.lang.asm.x86 on Tue Jul 19 17:36:23 2022
    From Newsgroup: comp.lang.asm.x86

    Hello all,

    I'm using Borlands Tasm32 (v5.0) and just ran into a situation where I had
    to call 'DllGetVersion' inside ComCtl32. The problem is that that function exists in several other DLLs (shell32 to name another).

    IOW, although I can write 'call DllGetVersion, ...' I never know which DLL will actually get called.

    My question:

    Does anyone here know if Tasm32 knows an assemble-time syntax to call a function from a specific DLL ? (would be handy for a few other functions too)

    Remarks:

    I currently used the runtime "LoadLibary", "GetProcAddress" solution, but thats cumbersome.

    I could also rename the function itself (from "DllGetVersion" to something like "ComCtl32_GetVersion") and rebuild the libarary, but thats a ... well, not a solution I'd really like either.

    Regards,
    Rudy Wieser

    P.s.
    Anyone knows where I can find ComCtl32 v6.x ?


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Frank Kotler@fbkotler@nospicedham.myfairpoint.net to comp.lang.asm.x86 on Tue Jul 19 21:50:38 2022
    From Newsgroup: comp.lang.asm.x86

    On 07/19/2022 11:36 AM, R.Wieser wrote:
    Hello all,

    Hi Rudy,
    Seems on-topic to me.

    Best,
    Frank


    I'm using Borlands Tasm32 (v5.0) and just ran into a situation where I had
    to call 'DllGetVersion' inside ComCtl32. The problem is that that function exists in several other DLLs (shell32 to name another).

    IOW, although I can write 'call DllGetVersion, ...' I never know which DLL will actually get called.

    My question:

    Does anyone here know if Tasm32 knows an assemble-time syntax to call a function from a specific DLL ? (would be handy for a few other functions too)

    Remarks:

    I currently used the runtime "LoadLibary", "GetProcAddress" solution, but thats cumbersome.

    I could also rename the function itself (from "DllGetVersion" to something like "ComCtl32_GetVersion") and rebuild the libarary, but thats a ... well, not a solution I'd really like either.

    Regards,
    Rudy Wieser

    P.s.
    Anyone knows where I can find ComCtl32 v6.x ?



    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From George Neuner@gneuner2@nospicedham.comcast.net to comp.lang.asm.x86 on Thu Jul 21 08:13:06 2022
    From Newsgroup: comp.lang.asm.x86

    On Tue, 19 Jul 2022 17:36:23 +0200, "R.Wieser" <address@nospicedham.not.available> wrote:

    I'm using Borlands Tasm32 (v5.0) and just ran into a situation where I had >to call 'DllGetVersion' inside ComCtl32. The problem is that that function >exists in several other DLLs (shell32 to name another).
    :
    Does anyone here know if Tasm32 knows an assemble-time syntax to call a >function from a specific DLL ? (would be handy for a few other functions >too)
    :
    I currently used the runtime "LoadLibary", "GetProcAddress" solution, but >thats cumbersome.

    Sorry, I never used Tasm (any version), but WRT to GetProcAddress I
    don't believe there is any other way to guarantee you will get the
    right function.

    One suggestion though:

    If you know the DLL is already resident - because you static linked or
    already have loaded it dynamically - you should use GetModuleHandle
    instead of LoadLibrary. Calls to LoadLibrary must be paired with
    calls to FreeLibrary because they maintain usage reference counts on
    the loaded module. If you don't pair them properly, modules can end up
    either prematurely unloaded or locked into memory.

    :
    Regards,
    Rudy Wieser

    P.s.
    Anyone knows where I can find ComCtl32 v6.x ?

    https://www.dll-files.com/comctl32.dll.html
    Look near the bottom of the page for 6.x

    Hope this helps.
    George

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From R.Wieser@address@nospicedham.not.available to comp.lang.asm.x86 on Thu Jul 21 15:43:03 2022
    From Newsgroup: comp.lang.asm.x86

    George,

    Sorry, I never used Tasm (any version), but WRT to GetProcAddress
    I don't believe there is any other way to guarantee you will get
    the right function.

    There is, and I mentioned it just below the 'GetProcAddress' method.

    If you know the DLL is already resident you should use GetModuleHandle instead of LoadLibrary.

    Does it make a difference ? (whats the 'should' about ?)

    Regards,
    Rudy Wieser


    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From George Neuner@gneuner2@nospicedham.comcast.net to comp.lang.asm.x86 on Thu Jul 21 11:55:30 2022
    From Newsgroup: comp.lang.asm.x86

    On Thu, 21 Jul 2022 15:43:03 +0200, "R.Wieser" <address@nospicedham.not.available> wrote:

    George,

    Sorry, I never used Tasm (any version), but WRT to GetProcAddress
    I don't believe there is any other way to guarantee you will get
    the right function.

    There is, and I mentioned it just below the 'GetProcAddress' method.

    Yes, but it involved recompiling the module. Most people are not in a
    position to rebuild system DLLs, so that isn't a general solution.


    If you know the DLL is already resident you should use GetModuleHandle
    instead of LoadLibrary.

    Does it make a difference ? (whats the 'should' about ?)

    'should' means it is the best choice ... at least under the given circumstances.


    And it does make a difference, which I explained previously and will
    expound on now:


    LoadLibrary manipulates reference counts on the loaded module and
    every call to LoadLibrary has to be paired with a call to FreeLibrary. Unbalanced calls to LoadLibrary can cause a shared DLL to end up
    locked into memory.
    [Note that application exit automatically calls FreeLibrary for all
    DLLs attached to the process. So application exit will balance one
    LoadLibrary call for any given library.]

    GetModuleHandle just searches for an already loaded module and returns
    a handle to it (that can be passed to GetProcAddress).


    If you are dealing with an already loaded DLL (for which you don't
    have a handle available), you have to do one of the following:
    (in C)

    hnd = GetModuleHandle( "ComCtl32" );
    ptr = GetProcAddress( hnd, "DllGetVersion" );

    or

    hnd = LoadLibrary( "ComCtl32" );
    ptr = GetProcAddress( hnd, "DllGetVersion" );
    FreeLibrary( hnd );

    Whenever you call LoadLibrary, you also have to call FreeLibrary
    UNLESS you are deliberately loading a /new/ DLL and intend it to
    remain resident until application exit. And if you do deliberately
    load something, you 'should' (best practice) save the returned handle
    because it is simpler than having to discover it again later.


    I realize the documentation[1,2] says application exit frees libraries regardless of reference counts ... but "free" in this case means
    "detached from your process" and it does not necessarily mean the
    library can or will be be unloaded from memory. In particular, if the
    library instantiates one or more COM objects based on LoadLibrary
    calls (which in general you can't know), and those loads are not
    balanced by FreeLibrary calls, the library will never be unloaded (ie.
    it will be locked into memory).

    NB: DLLs in Windows can have their own private heaps not associated
    with any client process. Objects created on a private heap on behalf
    of a client process might be able to survive the termination of that
    process. COM objects have their own reference counts which are
    unrelated to reference counts on the module that implements them.
    Windows will not unload any module that still has live COM objects.

    To be safe you need to make sure you always balance explicit
    LoadLibrary calls with FreeLibrary calls.


    Regards,
    Rudy Wieser

    Hope this helps.
    George

    [1] https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya
    [2] https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freelibrary

    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From R.Wieser@address@nospicedham.not.available to comp.lang.asm.x86 on Fri Jul 22 10:56:31 2022
    From Newsgroup: comp.lang.asm.x86

    George,

    I don't believe there is any other way to guarantee you will get
    the right function.

    There is, and I mentioned it just below the 'GetProcAddress' method.

    Yes, but it involved recompiling the module.

    So there /is/ a way, but you do not like it. Thats something quite different.

    Most people are not in a position to rebuild system DLLs,

    Whut ? Who has said anything about rebuilding *DLLs* ? (library, not DLL)

    so that isn't a general solution.

    I can't remember having said anything about it needing to work for everyone else too ...

    But yes, that is why I posted "not a solution I'd really like either" -
    *even though* I wager to guess that I'm the only one here who uses Borlands Tasm32 v5.x ....

    Regards,
    Rudy Wieser


    --- Synchronet 3.21d-Linux NewsLink 1.2