Solved

Delphi Programming question

Posted on 1997-08-30
17
189 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
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 

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

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Simple Delphi Question 9 90
QRReport  TQrmemo vertical stretching 1 46
Delphi 2 60
MS Access from Delphi 31 30
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.

778 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