Solved

How to detect a not installed system library?

Posted on 2001-06-15
9
152 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

705 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