?
Solved

How to detect a not installed system library?

Posted on 2001-06-15
9
Medium Priority
?
157 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 400 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
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.

 
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

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…
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…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses
Course of the Month9 days, 13 hours left to enroll

762 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