Solved

How to detect a not installed system library?

Posted on 2001-06-15
9
147 Views
Last Modified: 2010-04-06
I am using netbios 3.0 to find out the MAC-address. It is using the function 'Netbios' in the system dll 'netbios32.dll'. Now, my boss is afraid it will crash when the computer has no network installed (no netbios32.dll).

To simulate the situation where there's no such library, I changed the name in 'netbiosx.dll' and everything compiled fine. But Delphi says dll not found even before it started the application. try except didn't help.

Question:

How to declare a function and find out at run time this function doesn't exist?
0
Comment
Question by:dnoelpp
9 Comments
 
LVL 3

Author Comment

by:dnoelpp
ID: 6194649
Sorry, it should be 'netapi32.dll', not 'netbios.dll'.

And secondly, does someone of the experts know about the availability of the netbios on Windows machines and other machines (maybe on Linux)?
0
 
LVL 3

Author Comment

by:dnoelpp
ID: 6194652
With "availability" I mean, under which circumstances you can expect to find this dll? Under which circumstances not?
0
 
LVL 17

Accepted Solution

by:
geobul earned 100 total points
ID: 6194702
Hi,
The answer is: dynamic loading of the dll:

type
 TDLLFunction=function(a:integer; b: PChar): integer; stdcall;

var
 DLLFunction: TDLLFunction;
 Handle:THandle;
begin
 // load the library
 Handle:=LoadLibrary('test.dll');
 // check if it is loaded
 if Handle<>0 then begin
   try
    // get the address of the function
    @DLLFunction := GetProcAddress(Handle, 'DLLFunction');
   // now call the function
   DLLFunction(10, PChar('Hello'));
  finally
   // unload the library
   FreeLibary(Handle);
  end;
 end else begin
   // library not found
   ShowMessage('test.dll not found!');
 end;
end;

Regards, Geo
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 8

Expert Comment

by:Cesario
ID: 6196650
Hello dnoelpp,

I use this function to check if a DLL is installed :


Function DllOnSystem ( DllName:String):Boolean;
VAR
  Ret : Integer;
  good : Boolean;
Begin
  ret := LoadLibrary ( pChar(DllName));
  IF Ret>0 FreeLibrary ( ret );
  Result := Ret>0;
End;


Good Luck

Cesario
   
0
 
LVL 3

Expert Comment

by:Mathias
ID: 6198737
Listening...
0
 
LVL 3

Author Comment

by:dnoelpp
ID: 6201959
Thanks, but something is still unclear. The NetBios function is a function taking a pointer to a record (type PNCB) and returning a character. How do I call such a function dynamically?

And, does someone know about the availability of netapi32.dll? Especially can it happen that it is not present and under which circumstances?
0
 
LVL 3

Author Comment

by:dnoelpp
ID: 6205391
Okay, now I found it. About the availability of netapi32.dll I will post another question (perhaps in the networking topic).

This is my working solution (pasted together out of Cesario's and geobul's answers), thanks a lot! It will return a question mark if either no NIC or no netapi32.dll is installed.

*** ***

uses
 NB30;

type
  TNetBiosFunction = function(P: PNCB): Char; stdcall;

const
  NONETAPI32 = $ac;


// Invoke the NetBios function of the netapi32.dll
// dynamically. If netapi32.dll is not installed,
// return the character value of NONETAPI.
function NetBios(P: PNCB): Char;
var
  NetBiosFunction: TNetBiosFunction;
  Handle: THandle;
begin
  Handle := LoadLibrary('netapi32.dll');
  if Handle <> 0 then begin
    try
      @NetBiosFunction := GetProcAddress(Handle, 'Netbios');
      Result := NetBiosFunction(P);
    finally
      FreeLibrary(Handle);
    end;
  end else begin
    Result := Char(NONETAPI32);
  end;
end;

function GetAdapterInfo(Lana: Char): String;
var
 Adapter: TAdapterStatus;
 NCB: TNCB;
begin
 FillChar(NCB, SizeOf(NCB), 0);
 NCB.ncb_command := Char(NCBRESET);
 NCB.ncb_lana_num := Lana;
 if Netbios(@NCB) <> Char(NRC_GOODRET) then
 begin
   Result := '?';
   Exit;
 end;

 FillChar(NCB, SizeOf(NCB), 0);
 NCB.ncb_command := Char(NCBASTAT);
 NCB.ncb_lana_num := Lana;
 NCB.ncb_callname := '*';

 FillChar(Adapter, SizeOf(Adapter), 0);
 NCB.ncb_buffer := @Adapter;
 NCB.ncb_length := SizeOf(Adapter);
 if Netbios(@NCB) <> Char(NRC_GOODRET) then
 begin
   Result := '?';
   Exit;
 end;
 Result :=
   IntToHex(Byte(Adapter.adapter_address[0]), 2) + '-' +
   IntToHex(Byte(Adapter.adapter_address[1]), 2) + '-' +
   IntToHex(Byte(Adapter.adapter_address[2]), 2) + '-' +
   IntToHex(Byte(Adapter.adapter_address[3]), 2) + '-' +
   IntToHex(Byte(Adapter.adapter_address[4]), 2) + '-' +
   IntToHex(Byte(Adapter.adapter_address[5]), 2);
end;

function GetMACAddress: string;
var
 AdapterList: TLanaEnum;
 NCB: TNCB;
begin
 FillChar(NCB, SizeOf(NCB), 0);
 NCB.ncb_command := Char(NCBENUM);
 NCB.ncb_buffer := @AdapterList;
 NCB.ncb_length := SizeOf(AdapterList);
 Netbios(@NCB);
 if Byte(AdapterList.length) > 0 then
   Result := GetAdapterInfo(AdapterList.lana[0])
 else
   Result := '?';
end;
0
 
LVL 3

Author Comment

by:dnoelpp
ID: 6205447
0
 
LVL 17

Expert Comment

by:geobul
ID: 6205518
Hi,

type
// define NCB structure
NCB = record
 ncb_command : AnsiChar;
 ...
end;

// Define function type
TNetBios=function(pncb : NCB): AnsiChar; stdcall;

var
  NetBios: TNetBios;
  Handle:THandle;
  ncbVar : NCB;
  ret : AnsiChar;
begin
// load the library
Handle:=LoadLibrary('netapi32.dll');
// check if it is loaded
if Handle<>0 then begin
  try
   // get the address of the function
   @NetBios := GetProcAddress(Handle, 'NetBios');
  // Fill NCB structure
  ncbVar.ncb_command := CHR(4);
  // ...
  // now call the function
  ret := NetBios(ncbVar);
 finally
  // unload the library
  FreeLibary(Handle);
 end;
end else begin
  // library not found
  ShowMessage('netapi32.dll not found!');
end;
end;

I'm not sure about ncbVar type. It also could be:
type
  PNCB = ^NCB;
  NCB = record
.....

var
  ncbVar : PNCB;
----
So you can try both declarations.
About netapi32.dll : it is a part of windows networking. If a computer has no network installed, perhaps there won't be such a dll.

Regards, Geo
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question