09-04-2020, 09:26 AM
(This post was last modified: 09-04-2020, 09:43 AM by ZGabrovski@gmail.com.)
I can confirm now, that for sure the problem comes from openSSL dll library sharing between the host exe app and dll plugin library.
Main problem comes from Windows dll handlig - if you use one and the same dll library in the host app and in the plugin dll libray, Windows does not load fresh copy of dll library, it uses the same. allready loaded into host app, described here: https://stackoverflow.com/questions/1253...iple-times
In this case, this cause call of "LoadOpenSSLLibrary" twice, for one and the same OpenSLL library instance.
It mismatching call of "CRYPTO_set_locking_callback", and finally - it will call "CRYPTO_set_locking_callback(nil);" into dll plugin ibrary, which cause to fail an Openssl in main .exe application.
So - I did a following:
- I create a global DLL handle objects in IdSSLOpenSSLHeaders.pas unit:
and global critical section
and thread-safe methods for get/set values:
and move then
from "Implementaion" to "Interface" section;
and I modify a "load" method:
- modification of the both functions LoadOpenSSLLibrary and UnLoadOpenSSLLibrary in the IdSSLOpenSSL.pas - now they will check if the new "GlobalIdSSL " and "GlobalIdCrypto " object are assigned, they take the hadle from the variables instad of to load them from a Windows load library, and in that case - Do not call
CRYPTO_set_locking_callback method and all other funcions for init.
Now everything works fine. A pass a handles from the host .exe to the plugin dll library:
In my Host .exe code (delhi 10.3 rio):
In my plugin dll library (Lazarus 2.1 fpc 3.3.1)
That's all.
I try to attach changes here, but I can not. It will tell me "File type is not allowed".
I try to create a branch and open a new pull request, but it is not possible, as described here: https://stackoverflow.com/questions/3094...-in-github
My Github account is ZGabrovski.
Main problem comes from Windows dll handlig - if you use one and the same dll library in the host app and in the plugin dll libray, Windows does not load fresh copy of dll library, it uses the same. allready loaded into host app, described here: https://stackoverflow.com/questions/1253...iple-times
In this case, this cause call of "LoadOpenSSLLibrary" twice, for one and the same OpenSLL library instance.
It mismatching call of "CRYPTO_set_locking_callback", and finally - it will call "CRYPTO_set_locking_callback(nil);" into dll plugin ibrary, which cause to fail an Openssl in main .exe application.
So - I did a following:
- I create a global DLL handle objects in IdSSLOpenSSLHeaders.pas unit:
Code:
hGlobalIdSSL : TIdLibHandle = IdNilHandle;
hGlobalIdCrypto : TIdLibHandle = IdNilHandle;
and global critical section
Code:
csGlobalIDSSL : TIdCriticalSection;
and thread-safe methods for get/set values:
Code:
function GlobalIdSSL : TIdLibHandle;
function GlobalIdCrypto : TIdLibHandle;
procedure SetGlobalIdSSL ( fGlobalIdSSL : TIdLibHandle );
procedure SetGlobalIdCrypto ( fGlobalIdCrypto : TIdLibHandle );
and move then
Code:
hIdSSL : TIdLibHandle = IdNilHandle;
hIdCrypto : TIdLibHandle = IdNilHandle;
from "Implementaion" to "Interface" section;
and I modify a "load" method:
Code:
if hIdCrypto = IdNilHandle then begin
//
// Zdravko Gabrovski - Global OpenSSL handler implementation
//
if GlobalIdCrypto <> IdNilHandle then
hIdCrypto := GlobalIdCrypto
else begin
hIdCrypto := LoadSSLCryptoLibrary;
end;
if hIdCrypto = IdNilHandle then begin
FFailedLoadList.Add(IndyFormat(RSOSSFailedToLoad, [GIdOpenSSLPath + SSLCLIB_DLL_name {$IFDEF UNIX}+ LIBEXT{$ENDIF}]));
Exit;
end;
end;
if hIdSSL = IdNilHandle then begin
//
// Zdravko Gabrovski - Global OpenSSL handler implementation
//
if GlobalIdSSL <> IdNilHandle then
hIdSSL := GlobalIdSSL
else
hIdSSL := LoadSSLLibrary;
if hIdSSL = IdNilHandle then begin
FFailedLoadList.Add(IndyFormat(RSOSSFailedToLoad, [GIdOpenSSLPath + SSL_DLL_name {$IFDEF UNIX}+ LIBEXT{$ENDIF}]));
Exit;
end;
end;
- modification of the both functions LoadOpenSSLLibrary and UnLoadOpenSSLLibrary in the IdSSLOpenSSL.pas - now they will check if the new "GlobalIdSSL " and "GlobalIdCrypto " object are assigned, they take the hadle from the variables instad of to load them from a Windows load library, and in that case - Do not call
CRYPTO_set_locking_callback method and all other funcions for init.
Now everything works fine. A pass a handles from the host .exe to the plugin dll library:
In my Host .exe code (delhi 10.3 rio):
Code:
Params.Values['hIdSSL']:= hIdSSL.ToString; // from IdSSLOpenSSLHeaders
Params.Values['hIdCrypto']:= hIdCrypto.ToString; // from IdSSLOpenSSLHeaders
In my plugin dll library (Lazarus 2.1 fpc 3.3.1)
Code:
lhIdSSL := StrToUInt64Def( Tl.Values['hIdSSL'], 0 ); // Handler comes from host app
lhIdCrypto := StrToUInt64Def( Tl.Values['hIdCrypto'], 0 );
if ( lhIdSSL <> IdNilHandle ) and ( lhIdCrypto <> IdNilHandle ) then begin
SetGlobalIdSSL( lhIdSSL );
SetGlobalIdCrypto( lhIdCrypto );
LoadOpenSSLLibrary;
end;
That's all.
I try to attach changes here, but I can not. It will tell me "File type is not allowed".
I try to create a branch and open a new pull request, but it is not possible, as described here: https://stackoverflow.com/questions/3094...-in-github
My Github account is ZGabrovski.