Need to call ping32.dll from an InnoSetup script

Hi All,

I need to call the ping32.dll library from within an innosetup code section, which uses pascal. Problem is I don't know pascal and do not know how to call a dll.

There is an example of pascal in Innosetup calling an ODBC dll at http://www13.brinkster.com/vincenzog/isxart.asp?idart=52


The DLL call is defined in VB as follows (zip file that includes the ping32.dll package at http://www.winnetmag.com/Files/562/562.zip):

    Declare Function ping _

    Lib "ping32.dll" _

    (ByVal sHostName$, _

    ByVal sIPAddr$, _

    ByVal iDataLen%, _

    lPingTime&, _

    ByVal iTimeout%, _

    ByVal iVerbose%) As Integer

With the following writeup:

--------------------------
 The first parameter of the ping function is a string containing either the name or the IP address of the system to be pinged. The second parameter is a string that the ping function returns. This string contains the IP address of the pinged system. This parameter lets the calling program retrieve the IP address for a given TCP/IP host name. The third parameter specifies the size of the data packet sent with the ping. The maximum data length that ping32.dll allows is 1024 bytes. The fourth parameter, a long variable, returns the elapsed milliseconds the ping function required to execute. The fifth parameter contains the maximum time in milliseconds that the ping function waits for a response for sent or received packets. The sixth parameter specifies the mode of operation for the ping function. If you set this parameter to True, ping32.dll runs in verbose mode, the mode that displays all ping results and errors in a message box. Setting the sixth parameter to False runs ping32.dll in silent mode, the mode that reports any ping results and errors in the ping function's return code and output parameters.
-----------------------------

My last attempt was to call ping.exe directly as follows:

procedure TestOnClick(Sender: TObject);
var
      bReturn: boolean;
      iResultCode: integer;
      sArgs: string;
begin
      WizardForm.Enabled := false;

      sArgs := '-n 1 ' + txtIPaddress.Text;
      Msgbox(sArgs,0,0);
      bReturn := InstExec('ping.exe','-n 1' + IPaddress,'',True,False,SW_HIDE,iResultCode);
      Msgbox(IntToStr(iResultCode),0,0);

      WizardForm.Enabled := true;
end;

I just want to show a yes/no messagebox to inform the user as to whether the IP they provided is live.
LVL 17
SqueebeeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

GloomyFriarCommented:
var
hLib: THandle;
PingTime: longint;
 _imp_ping: function(sHostName, sIPAddr: PCHAR; iDataLen: longint; lPingTime: PLONG; iTimeout: longint; iVerbose: longint) : longint; stdcall;

begin
 hLib := LoadLibrary ('ping32.dll');
 if hLib = 0 then begin
   ShowMessage('Load ping32.dll error');
   Exit;
 end;

 @_imp_ping  := GetProcAddress ( hLib, 'ping' );
 if _imp_ping = nil then begin
   ShowMessage('Load func ping error');
   Exit;
end;

  // Call to the function
 _imp_ping('SomeHost', '192.168.1.15', 128, @PingTime, 100, 1);
end;
0
SqueebeeAuthor Commented:
Umm, is there a function header that was not pasted at the top?
0
GloomyFriarCommented:
If you like that it'll be a function then add some header.
For example
function MakePing(sHostName, sIPAddr: PCHAR; iDataLen: longint; lPingTime: PLONG; iTimeout: longint; iVerbose: longint): longint;
var
hLib: THandle;
PingTime: longint;
_imp_ping: function(sHostName, sIPAddr: PCHAR; iDataLen: longint; lPingTime: PLONG; iTimeout: longint; iVerbose: longint) : longint; stdcall;

begin
hLib := LoadLibrary ('ping32.dll');
if hLib = 0 then begin
  ShowMessage('Load ping32.dll error');
  Exit;
end;

@_imp_ping  := GetProcAddress ( hLib, 'ping' );
if _imp_ping = nil then begin
  ShowMessage('Load func ping error');
  Exit;
end;

 // Call to the function
 Result := _imp_ping(sHostName, sIPAddr, 128, lPingTime, iTimeout, iVerbose);
end;

0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

GloomyFriarCommented:
Try to run the following command and show me the result:

tdump -ee ping32.dll
0
SqueebeeAuthor Commented:
System does not recognize tdump.
0
GloomyFriarCommented:
Which compiler do you use?
0
SqueebeeAuthor Commented:
And I get an unknown type: PLONG error when I try to compile my innosetup script.
0
SqueebeeAuthor Commented:
I am useing InnoSetup, Innosetup is written in Delphi and uses a pascal parser to supply customization.
0
GloomyFriarCommented:
Replace PLONG with PULONG
and
if _imp_ping = nil then begin
with
if @_imp_ping = nil then begin
0
GloomyFriarCommented:
I have to go now. Sorry.
See you tomorrow.
0
SqueebeeAuthor Commented:
Hmm, didn't like pulong either.
0
SqueebeeAuthor Commented:
Thanks for your help so far.
0
raidosCommented:
PULONG is probably

Type
  PULONG = ^Cardinal;

But if you include Windows in your uses clause you should have PULONG defined and ready..

Regards
//raidos
0
SqueebeeAuthor Commented:
I have absolutely no clue what you are talking about. I have zero pascal knowledge.
0
gmayoCommented:
This will at least compile and run, as to the results, well I don't know enough about the function call. Perhaps reading the doco in full will reveal any potential problems.

unit Unit1;

interface

uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;

type
      TForm1 = class(TForm)
            Button1: TButton;
            procedure Button1Click(Sender: TObject);
      private
            { Private declarations }
      public
            { Public declarations }
      end;

var
      Form1: TForm1;

implementation

{$R *.dfm}

const
      DLLNAME = 'ping32.dll';

function ping(HostName : PChar; var IPAddress : PChar; IDataLen : cardinal;
      var Time : cardinal; timeout : cardinal; verbose : boolean) : cardinal; stdcall; external DLLNAME;

procedure TForm1.Button1Click(Sender: TObject);
var
      buf : string[128];
      time : cardinal;
      p : PChar;
      res : cardinal;
begin
      p := @buf[1];
      time := 1000;
      res := Ping('127.0.0.1', p, 128, time, time, false);
end;

end.


Geoff M.
0
SqueebeeAuthor Commented:
unit Unit1;

interface

uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

type
     TForm1 = class(TForm)
          Button1: TButton;
          procedure Button1Click(Sender: TObject);
     private
          { Private declarations }
     public
          { Public declarations }
     end;

These are not used in an InnoSetup [Code] block. I think I may have to investigate the example of a working InnoSetup dll call and try to modify the suggestions given to work with it.
0
gmayoCommented:
"These are not used in an InnoSetup [Code] block" - well, no, since the zip doesn't contain any Delphi units. What I've posted is a full unit which *calls* the DLL in the way that DLLs are usually called from Delphi, and which includes an *example* of how to use it (a common way of expressing examples in this EE forum). Although Gloomy has posted a *different* way to access the DLL, it's not necessarily the *best* way (to be fair, there are fors and againsts for both methods).

Geoff M.
0
gmayoCommented:
Beg your pardon, the *second* zip containing the DLL didin't have any Delphi source. However, the first zip doesn't appear to call the Ping routine anyway... unless I've missed it?

Geoff M.
0
SqueebeeAuthor Commented:
I found the DLL by looking at a VB example that calls it. There is no delphi or pascal calling it at all, if there was a pascal example in the zip I may have just used it instead of coming here. I am awarding 500 points because I do not know Pascal/Delphi and therefore was looking for a solution I could drop in with little modification.
0
GloomyFriarCommented:
It's me again.
Are there any problems with my code?
0
Lee_NoverCommented:
I'musing this function from my dll in a setup
function SignalEvent(AEventName: string): Boolean; external 'SignalEvent@files:lnEventControl.dll stdcall';


your code would translate to:
function ping(sHostName, sIPAddr: string; iDataLen, lPing, iTimeout, iVerbose: Integer): Integer; external 'ping@files:ping32.dll stdcall';
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
SqueebeeAuthor Commented:
Hi everyone,

Thanks for your input. I have split up the points and I am calling Lee_Nover's solution the accepted answer as it relates most directly to my implementation.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Pascal

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.