#1 2026-07-10 08:07:55

zed
Member
Registered: 2015-02-26
Posts: 122

Usage of SetDllDirectoryW within the framework

In my application, I encountered an issue with mORMot 2: dynamically loading libcurl via LibCurlInitialize([giAll], 'libcurl-4.dll') results in a call to SetDllDirectoryW(nil). This breaks subsequent LoadLibrary calls for loading third-party DLLs. The problem arises because my application calls SetDllDirectoryW at startup to set a global DLL directory.

After analyzing the DLL loading algorithm in mORMot 2, I would like to propose a few improvements:

1. When loading libcurl, use the TryFromExecutableFolder option instead of forcibly appending the absolute path Executable.ProgramFilePath + dllname (which, by the way, is done without checking whether dllname is relative or absolute).

// mormot.lib.curl
procedure LibCurlInitialize
...
  curl := TLibCurl.Create;
  {$ifdef OSWINDOWS}
  curl.TryFromExecutableFolder := True;                     // << fix
  {$endif OSWINDOWS}
  curl.TryLoadResolve([    
    //{$ifdef OSWINDOWS}
    // first try the libcurl.dll in the local executable folder
    //Executable.ProgramFilePath + dllname,           // << fix
    //{$endif OSWINDOWS}
    // search standard library in path
    dllname
    ...

2. Inside TryLoadLibrary, invoke LibrarySetDirectory only if the path differs from Executable.ProgramFilePath.

// mormot.core.os
function TSynLibrary.TryLoadLibrary
...
  if (nwd <> '') and (nwd <> Executable.ProgramFilePath) then                       // << fix
  begin
    GlobalLock; // SetDllDirectoryW() is for the whole process not thread
    if not LibrarySetDirectory(nwd) then // as documented on microsoft.com
    begin
      GlobalUnLock;
      nwd := '';
    end;
  end else 
    nwd := '';                            // << fix

3. Add a global variable LibraryUseSetDllDirectory to mormot.core.os to allow completely disabling SetDllDirectoryW within the framework.

// mormot.core.os
var
  LibraryUseSetDllDirectory: boolean; // = False by default

Last edited by zed (2026-07-10 08:12:53)

Offline

#2 Yesterday 17:35:01

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 15,554
Website

Re: Usage of SetDllDirectoryW within the framework

Sorry for being late, but I looked back at this post.
And I am confused.

1) has no difference with the existing code.

2) I don't think it is how it is supposed to work

3) this I can understand: if you call LibrarySetDirectory() manually, then you don't want to have the framework code interferring...
BUT what I don't get is that LibrarySetDirectory() is recursive and we properly call LibrarySetDirectory(nil) with GlobalLock/Unlock to ensure it won't conflict anywhere.

So my first fix/improvement is to add a TSynLibrary.DisableLibrarySetDirectory property for each instance:
https://github.com/synopse/mORMot2/commit/a573d477f

Then a new DefaultDisableLibrarySetDirectory global variable, used as default for TSynLibrary.DisableLibrarySetDirectory property value on Windows:
https://github.com/synopse/mORMot2/commit/d26c74a04

Offline

Board footer

Powered by FluxBB