Solved

How to detect a not installed system library?

Posted on 2001-06-15
9
136 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
 
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

707 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now