17

I made an application that uses the openssl dlls (libeay32.dll and ssleay32.dll). It is indy using them, I don't call the dlls directly.

The simplest workaround i found to avoid an installer (i just delpoy an exe and i am ok with this approach) is to:

  1. put the dlls as resources of the exe
  2. on program start I extract them in the exe folder
  3. the exe uses them

This is perfect but I would like to improve the approach by extracting the dlls in a temp folder and not on the exe folder (that in many cases is the desktop).

The problem is that I don't know how to force the application to use the dlls in the temp folder, because now the behaviour is: if dlls are not in current directory try to search in the directories defined in the system path.

Who knows a solution to force indy to use the dlls in my temp path? (like "temporarly registering the dlls")

Bruno
  • 119,590
  • 31
  • 270
  • 376
UnDiUdin
  • 14,924
  • 39
  • 151
  • 249
  • one way would be: look at how Indy is loading those dlls and modify those *.pas files and put them in your project directory, then you're pretty much out of the woods. –  Nov 07 '12 at 11:57
  • @ComputerSaysNo I use Indy as a blackbox, I am not lazy, but i remember once i read about the possibility of using a dll outside the system path by "kind of registering" it at program startup. THis would be the best for me. May be the fact Indy and not me is using those dlls is not important. – UnDiUdin Nov 07 '12 at 12:02
  • I think you should change your question then... another way would be to leave the functionality as is and simply hide the files, then delete them when application closes. –  Nov 07 '12 at 12:19
  • P.S. you can also try a different approach, if the application is not in the temp folder, copy itself there, start it and close, then everything works as you want it. –  Nov 07 '12 at 12:20
  • 5
    If you loaded the DLLs with LoadLibrary explicitly as soon as you have written them to the temp folder, would not this satisfy a later LoadLibrary call? – frogb Nov 07 '12 at 12:38
  • @frogb Yes, that would work. Also, I think you should post this as an answer, it's probably the best solution. – Ondrej Kelle Nov 07 '12 at 12:42
  • 1
    Just another idea: if you use SetEnvironmentVariable and change the PATH variable to point to your folder with the DLL...won't loadLibrary be tricked to use the new path? Not tested idea :) – iPath ツ Nov 07 '12 at 12:44
  • 5
    @DavidHeffernan _If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first._ – Ondrej Kelle Nov 07 '12 at 12:50
  • Both solutions are interesting :) This is a common problem with Indy when using SSL :) – iPath ツ Nov 07 '12 at 12:56
  • @TOndrej Yep, humble pie for lunch today for me! I'm deleting my bogus comments. – David Heffernan Nov 07 '12 at 12:59
  • @TOndrej Thanks for your support: my original comment was a question! – frogb Nov 07 '12 at 13:09
  • @iPath That would work, too. (I've tested it.) – Ondrej Kelle Nov 07 '12 at 15:12
  • How will users be able to install updated versions of the OpenSSL DLL? When security issues are found and a new OpenSSL version appears, normal DLLs could be replaced much easier and faster. – mjn Nov 08 '12 at 07:00

3 Answers3

21

If you are using an up-to-date version of Indy 10, the IdSSLOpenSSLHeaders unit has a public IdOpenSSLSetLibPath() function to tell Indy which custom folder to look in for the OpenSSL DLLs:

procedure IdOpenSSLSetLibPath(const APath: String);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks, anyawy in IdSSLOpenSSLHeaders unit I don't have IdOpenSSLSetLibPath(), means I need to update ? I have 10.5.8.0 – UnDiUdin Nov 08 '12 at 13:53
  • 1
    Yes, you would need to update, unless you patch your existing version manually. – Remy Lebeau Nov 08 '12 at 17:29
  • @RemyLebeau I am updating, but should i trust the SVN version? Which version is it? THanks – UnDiUdin Mar 18 '14 at 14:46
  • The current trunk version is 10.6.0 rev 5114. – Remy Lebeau Mar 18 '14 at 15:38
  • @RemyLebeau thanks, i am double posting, anyway i really am stuck i don't remember how i managed to upgrade indy according to the instructions http://stackoverflow.com/questions/3204601/step-by-step-upgrade-of-indy-10-in-delphi-2009 isn't there a more up to time upgrading instructions? i am not able even to locate packages now. – UnDiUdin Mar 19 '14 at 12:50
  • Update: i managed to open packages but i got compilation error: [DCC Fatal Error] IdGlobal.pas(1953): F2063 Could not compile used unit 'IdException.pas' i should wait for tomorrow build? – UnDiUdin Mar 19 '14 at 12:56
  • The [install instructions](http://indyproject.org/Sockets/Docs/Indy10Installation.aspx) are available on Indy's website. "Could not compile used unit ..." is a side effect of earlier errors in the compile. Troubleshooting compiler errors does not belong in this discussion. Please post a new question for it. – Remy Lebeau Mar 19 '14 at 14:56
16

Load the DLLs yourself with LoadLibrary as soon as you have written them to the temp folder.
This will make Indy's LoadLibrary use your DLLs when they need them:

If lpFileName does not include a path and there is more than one loaded module with the same base name and extension, the function returns a handle to the module that was loaded first.

kobik
  • 21,001
  • 4
  • 61
  • 121
frogb
  • 2,040
  • 15
  • 22
  • 1
    I just took this excellent idea and applied it to my .net p/invoke interface unit that provides access to my native library. It makes linking easier. Nice. – David Heffernan Nov 07 '12 at 16:33
  • Finally i used the tecnique suggested in this answer (`LoadLibrary`), that made me succeed without the need to upgrade Indy that it is a painful thing (everytime i tried to upgrade i failed: too many manual things to do). – UnDiUdin Feb 19 '15 at 15:03
10

You can use SetDllDirectory to manipulate the DLL search order.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 2
    +1, but surely modifying the Indy sources should be the last resort (which is exactly what I did with my application). I prefer your solution which is in my opinion the *correct* way do go. – kobik Nov 07 '12 at 13:28
  • @kobik On reflection, I agree. I actually really like frogb's solution now that I am convinced that it works. I was labouring under an incorrect understanding of how `LoadLibrary` works. – David Heffernan Nov 07 '12 at 13:30