Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Delphi Programming question

Posted on 1997-08-30
17
Medium Priority
?
198 Views
Last Modified: 2010-04-04
I am looking for a way to find a network card's hardware address.  This is the address that uniquely identifies it on a network.  The network card will be in a computer running Windows 95 or possibly NT.  Can you tell me a way of getting this address from either or both of these operating systems? I know this is a tough question but I only have 55 points to spare.  Sorry.
0
Comment
Question by:tdiamond
[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
  • 8
  • 7
  • 2
17 Comments
 
LVL 1

Expert Comment

by:sassas081597
ID: 1343121
I think this is your case. Sorry not in Pascal, however you can convert it from C to Pascal yourself.
NCB is a record. You need its fourth parameter.

UCHAR Netbios( PNCB:  pncb) {address of network control block};

typedef struct _NCB { // ncb
    UCHAR  ncb_command;
    UCHAR  ncb_retcode;
    UCHAR  ncb_lsn;
    UCHAR  ncb_num;
    PUCHAR ncb_buffer;
    WORD   ncb_length;
    UCHAR  ncb_callname[NCBNAMSZ];
    UCHAR  ncb_name[NCBNAMSZ];
    UCHAR  ncb_rto;
    UCHAR  ncb_sto;
    void (*ncb_post) (struct _NCB *);
    UCHAR  ncb_lana_num;
    UCHAR  ncb_cmd_cplt;
    UCHAR  ncb_reserve[10];
    HANDLE ncb_event;
} NCB;

ncb_lana_num

Specifies the LAN adapter number. This zero-based number corresponds to a particular transport provider using a particular LAN adapter board.

0
 

Author Comment

by:tdiamond
ID: 1343122
How can you find out the address of the network control block and will it be different depending on the computer?
0
 
LVL 1

Expert Comment

by:sassas081597
ID: 1343123
The Netbios function gives you all the information you need about the network controlblock as shown in the answer above.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:tdiamond
ID: 1343124
I don't mean to keep bugging you, but do you think that you could give me more info on where to put the struct and where to execute the Netbios function that you mentioned (in a header file or in your main.cpp file?)  I would like to try what you suggested in C or C++ before I convert it to Delphi/Pascal, but I'm having trouble getting it to compile.  I am using Microsoft C++ 4.0.  Could you possibly give me the minimal amount of C code to get it to work and tell me where to put it (.h,.cpp) just so that I don't have to keep bugging you.  I'd really appreciate it.

Thanks...
0
 

Author Comment

by:tdiamond
ID: 1343125
I don't mean to keep bugging you, but do you think that you could give me more info on where to put the struct and where to execute the Netbios function that you mentioned (in a header file or in your main.cpp file?)  I would like to try what you suggested in C or C++ before I convert it to Delphi/Pascal, but I'm having trouble getting it to compile.  I am using Microsoft C++ 4.0.  Could you possibly give me the minimal amount of C code to get it to work and tell me where to put it (.h,.cpp) just so that I don't have to keep bugging you.  I'd really appreciate it.

Thanks...
0
 

Author Comment

by:tdiamond
ID: 1343126
I don't mean to keep bugging you, but do you think that you could give me more info on where to put the struct and where to execute the Netbios function that you mentioned (in a header file or in your main.cpp file?)  I would like to try what you suggested in C or C++ before I convert it to Delphi/Pascal, but I'm having trouble getting it to compile.  I am using Microsoft C++ 4.0.  Could you possibly give me the minimal amount of C code to get it to work and tell me where to put it (.h,.cpp) just so that I don't have to keep bugging you.  I'd really appreciate it.

Thanks...
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1343127
Hi
Do you still have any problems and waiting for help ?
0
 

Author Comment

by:tdiamond
ID: 1343128
Yes, I still need help.  I still haven't received a reply to my last comment (which I mistakenly posted 3 times).  I am new to C/C++ and would like more information on how to implement the 'struct' that was given to me by sassas.  I put it all in one file (along with the netbios function call) and it bombed with 50 or more compiler errors.  A snippet of code that is known to work in MS C++ 4.0 (if possible), would be great.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1343129
Ok here is the code to list all network card's number in you'r system. I don't know which Version of Delphi so if You have Delphi2 please enable dirrective for this "$Define ForD2"

unit Unit1;

interface

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

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

{ $Define ForD2}   { Define This if You have Delphi2 }
{$IFDEF ForD2}
  function Netbios(P: Pointer): Char; stdcall;
{$ENDIF}

var
  Form1: TForm1;

implementation

{$R *.DFM}

{$IFNDEF ForD2}
uses
  NB30;

{$ELSE}
function Netbios; external 'netapi32.dll' name 'Netbios';


const
  NCBNAMSZ   = 16;             // absolute length of a net name
  MAX_LANA   = 254;            // lana's in range 0 to MAX_LANA inclusive
  NCBRESET   = $32;            // NCB RESET
  NCBASTAT   = $33;            // NCB ADAPTER STATUS
  NCBENUM    = $37;            // NCB ENUMERATE LANA NUMBERS

type
  // Network Control Block
  PNCB = ^TNCB;
  TNCBPostProc = procedure(P: PNCB);
  TNCB = packed record
    ncb_command: Char;         // command code
    ncb_retcode: Char;         // return code
    ncb_lsn: Char;             // local session number
    ncb_num: Char;             // number of our network name
    ncb_buffer: PChar;         // address of message buffer
    ncb_length: Word;          // size of message buffer
    ncb_callname: array[0..NCBNAMSZ - 1] of char;  // blank-padded name of remote
    ncb_name: array[0..NCBNAMSZ - 1] of char;      // our blank-padded netname
    ncb_rto: Char;             // rcv timeout/retry count
    ncb_sto: Char;             // send timeout/sys timeout
    ncb_post: TNCBPostProc;    // POST routine address
    ncb_lana_num: Char;        // lana (adapter) number
    ncb_cmd_cplt: Char;        // 0xff => commmand pending
    ncb_reserve: array[0..9] of Char;              // reserved, used by BIOS
    ncb_event: THandle;        // HANDLE to Win32 event which
                               // will be set to the signalled
                               // state when an ASYNCH command
                               // completes
  end;

  // Structure returned to the NCB command NCBASTAT is ADAPTER_STATUS followed
  // by an array of NAME_BUFFER structures.
  PAdapterStatus = ^TAdapterStatus;
  TAdapterStatus = packed record
    adapter_address: array[0..5] of Char;
    rev_major: Char;
    reserved0: Char;
    adapter_type: Char;
    rev_minor: Char;
    duration: Word;
    frmr_recv: Word;
    frmr_xmit: Word;
    iframe_recv_err: Word;
    xmit_aborts: Word;
    xmit_success: DWORD;
    recv_success: DWORD;
    iframe_xmit_err: Word;
    recv_buff_unavail: Word;
    t1_timeouts: Word;
    ti_timeouts: Word;
    reserved1: DWORD;
    free_ncbs: Word;
    max_cfg_ncbs: Word;
    max_ncbs: Word;
    xmit_buf_unavail: Word;
    max_dgram_size: Word;
    pending_sess: Word;
    max_cfg_sess: Word;
    max_sess: Word;
    max_sess_pkt_size: Word;
    name_count: Word;
  end;

  // Structure returned to the NCB command NCBENUM.
  // On a system containing lana's 0, 2 and 3, a structure with
  // length =3, lana[0]=0, lana[1]=2 and lana[2]=3 will be returned.
  PLanaEnum = ^TLanaEnum;
  TLanaEnum = packed record
    length: Char;         //  Number of valid entries in lana[]
    lana: array[0..MAX_LANA] of Char;
  end;
{$ENDIF}

procedure TForm1.Button1Click(Sender: TObject);
var
  MyNCB     : PNCB;
  AdaptStat : PAdapterStatus;
  LanaEnum  : PLanaEnum;
  i         : integer;
begin
  Memo1.Clear;
  New(MyNCB);
  New(AdaptStat);
  New(LanaEnum);
  MyNCB^.ncb_command := chr(NCBRESET);
  MyNCB^.ncb_lana_num := '0';
  if NetBios( MyNCB )<>#0 then
    ShowMessage( 'Error on RESET' )
  else
    begin
      MyNCB^.ncb_command := chr(NCBENUM);
      MyNCB^.ncb_callname := '*               ';
      MyNCB^.ncb_buffer := PChar( LanaEnum );
      MyNCB^.ncb_length := SizeOf(TLanaEnum);
      if NetBios( MyNCB )<>#0 then
        ShowMessage( 'Error on LANAENUM' )
      else
        begin
          MyNCB^.ncb_command := chr(NCBASTAT);
          MyNCB^.ncb_buffer := PChar( AdaptStat );
          MyNCB^.ncb_length := SizeOf(TAdapterStatus);
          for i:=0 to integer(LanaEnum^.length)-1 do
          begin
            MyNCB^.ncb_lana_num := LanaEnum^.lana[i];
            if NetBios( MyNCB )=#0 then
              Memo1.Lines.Add(
                'Adapter nr '+IntToStr(i)+' addr='+
                IntToStr(integer(PAdapterStatus(MyNCB^.ncb_Buffer).adapter_address[0]))+':'+
                IntToStr(integer(PAdapterStatus(MyNCB^.ncb_Buffer)^.adapter_address[1]))+':'+
                IntToStr(integer(PAdapterStatus(MyNCB^.ncb_Buffer)^.adapter_address[2]))+':'+
                IntToStr(integer(PAdapterStatus(MyNCB^.ncb_Buffer)^.adapter_address[3]))+':'+
                IntToStr(integer(PAdapterStatus(MyNCB^.ncb_Buffer)^.adapter_address[4]))+':'+
                IntToStr(integer(PAdapterStatus(MyNCB^.ncb_Buffer)^.adapter_address[5]))
                );
          end;
        end;
    end;
  Dispose(LanaEnum);
  Dispose(AdaptStat);
  Dispose(MyNCB);
end;

end.

Regards
Mirek
0
 

Author Comment

by:tdiamond
ID: 1343130
I tried the code you gave me and it didn't list any card addresses in the memo component.  I'm using using Delphi 3.0.  I have an SMC PCI 10Mbps Etherpower Network card and it didn't find it.  What am I doing wrong?  
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1343131
I don't know. Have You any error messages ? Try debug - this code was tested on My Win95 and created with Delphi3, however i tested this in Delphi2 too. Describe  more what is going on.

BTW  The card must be properlly installed in You'r Windows, but i think so you have this.
0
 

Author Comment

by:tdiamond
ID: 1343132
I tried it in Delphi 2.0 and 3.0 and it doesn't work in either.  It reports no error messages.  The problem is that it never enters into the "For" loop below because the expression "integer(LanaEnum^.length)-1" equals zero or NULL so the loop never executes even once.  Do you think the fact that my card is PNP is causing trouble?  What kind of card did you test this code on?

  ShowMessage( 'Error on LANAENUM' )
else
  begin
    MyNCB^.ncb_command := chr(NCBASTAT);
    MyNCB^.ncb_buffer := PChar( AdaptStat );
    MyNCB^.ncb_length := SizeOf(TAdapterStatus);
**   for i:=0 to integer(LanaEnum^.length)-1 do  **
      begin
        MyNCB^.ncb_lana_num := LanaEnum^.lana[i];
        if NetBios( MyNCB )=#0 then
          Memo1.Lines.Add(
          'Adapter nr '+IntToStr(i)+' addr='+ .....
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1343133
This enumerates all cards in Network so Dialup too. I just start try when this can happened, but now i don't know.

p.s. LanaEnum^.length=0 means so you have not Network adapters available for netbios calls.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1343134
Hi
My code don't work when you are conected to internet (mayby in some other situation). I will try to resolve this.
0
 

Author Comment

by:tdiamond
ID: 1343135
I do have a PPP dialup adapter set up which permits me to dial
into my ISP.  Do you think I should remove it from my device
list and run the program again to try to find my NIC card?
0
 
LVL 3

Accepted Solution

by:
mirek071497 earned 20 total points
ID: 1343136
NO !!!!

I only found where is the mistake.

I corrected this now.

When you have more than one network then you must set correct caller_name.

add in this proc varialble

var
  name_len  : DWORD;

and change code :

       MyNCB^.ncb_callname := '*               ';

to this :

      { getting UserName }
      name_len := SizeOf(MyNCB^.ncb_callname) ;
      GetUserName( @MyNCB^.ncb_callname, name_len );
      for i := 0 to name_len-1 do MyNCB^.ncb_callname[i] := UpCase(MyNCB^.ncb_callname[i]);
      for i := name_len-1 to SizeOf(MyNCB^.ncb_callname) do MyNCB^.ncb_callname[i]:=#32;
      { end of setting UserName }


all ned works fine.
0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1343137
BTW when you copy from Ex-Ex then probably spaces in ncb_callname was truncated.

ncb_callname must be filled to length=16 with spaces. This is problem with Ex-Ex.
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses

670 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