Solved

Delphi Programming question

Posted on 1997-08-30
17
187 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
  • 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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 10 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Printing problem 2 80
Delphi IDE crash without error message ... 7 75
Find and Replace Stream with 0s 8 56
update joined tables 2 27
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

911 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

21 Experts available now in Live!

Get 1:1 Help Now