• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 907
  • Last Modified:

DCPCrypt thread issues

I have a very simple function in a DLL.  My problem is that the DLL will get an exception every once in a while.  The exception is "Invalid Pointer".  I get this error when I am calling the DLL from 2 different threads.  Is DCPCrypt thread-safe and can I do to insure I am using DCPCrypt correctly.
function SHA1(aInputStr: PChar;
              var aHash: PChar): Integer; stdcall;
var
  tHash      : TDCP_sha1;
  sHash      : string;
  sHex       : string;
  Digest     : array of Byte;
  i          : integer;
 
begin
  if (State <> READY) and (State <> PUST_IN_PROGRESS) then begin
    // Error - DLL is in an invalid state to perform this operation
    Result := 1;
    Exit;
  end;
  try
    tHash  := TDCP_sha1.Create(nil);
    try
      tHash.Init;
      tHash.UpdateStr(StrPas(aInputStr));
      // Generate the Hash
      SetLength(Digest, tHash.HashSize div 8);
      tHash.Final(Digest[0]);
      sHash := '';
      for i := 0 to Length(Digest) - 1 do begin
        sHex := IntToHex(Digest[i], 2);
        sHash := sHash + sHex;
      end;
 
      if (Get_Memory(Pointer(aHash), Length(sHash))) then begin
        // return the CipherText
        StrPCopy(aHash, sHash);
        Result := 0;
      end else begin
        Result := 2;
        LogInfo('SHA1: ', 'Error allocating memory');
      end;
    finally
      tHash.Free;
    end;
  except
    on E: Exception do begin
      State  := SHA1_HASH_EXCEPTION;
      Result := 2;
      LogInfo('SHA1_HASH_EXCEPTION:', E.Message );
    end;
  end;
end;

Open in new window

0
rayman3411
Asked:
rayman3411
  • 2
1 Solution
 
2266180Commented:
I don't know about DCPCrypt but if it's not thread safe, you can fix that pretty easily like this:

assuming your funciton is declared like this:

function SHA1(aInputStr: PChar;
              var aHash: PChar): Integer; stdcall; external 'yourdll.dll';

you will make another function named

function sha1_(aInputStr: PChar; var aHash: PChar): Integer; // youc an choose any name you want, this is just an example
begin
  cs.acquire;
  try
    result:=sha1(aInputStr, aHash);
  finally
    cs.release;
  end;
end;

and declare a global variable like:

implementation

uses SyncObjs;

var cs:TCriticalSection;

.. functions here, including sha1_ ...

initialization
  cs:=TCriticalSection.Create;

finalization
  freeandnil(cs);

end.// end of unit

and then replace all your sha1 calls with sha1_
same goes for any other function which uses the same dll
0
 
aikimarkCommented:
ciuly

DCPcrypt - Delphi Cryptography Package (open source / MIT licensed)
http://www.cityinthesky.co.uk/cryptography.html

I haven't found anyone discussing whether it is thread-safe or not.

Is it possible that he needs
   tHash.Free;
in the EXCEPT clause of the (nested) TRY statements?
0
 
2266180Commented:
>> in the EXCEPT clause of the (nested) TRY statements?

NEVER. trhe except clause executes only on exception. the finally clause executes EVERY time. correct way is
create resource
try
  use resource
finally
  destroy resource
end;

PS: I don't have time to dig in the DCPcrypt source to check.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now