不要なMACアドレスを取得しない為には?

解決


くじら  2003-01-16 23:38:05  No: 2606

こんにちわ、くじらと申します。
こちらの過去ログのWindows2000でMACアドレスを取得する方法をやってみたのですが、おかしなMACアドレスが取得されてしまいます。
ipconfigで確認しても表示されない物で、明らかに使用していないMACアドレスです。
現象は
・毎日取得すると毎日違う物が取得される
・全てのパソコンでこの現象が発生するわけではない

なにか原因と思われることがあれば教えてください。
コードは過去ログのものをそのままで試してもダメでした。

あいまいな質問ですいませんがよろしくお願いします。


にしの  2003-01-17 02:34:34  No: 2607

過去ログというと、私が回答した
https://www.petitmonte.com/bbs/answers?question_id=84
だと思いますが、うまくいかないというのは、このコードまるまる使ってもだめということでしょうか。
# 空白を全角にしてあるので半角スペース2つに置き換える必要があります
XPではうまく動いているのですが。

毎日違うということは、同じ日なら同じものが取得されるということでしょうか。


くじら  2003-01-17 18:09:11  No: 2608

にしのさんレスありがとうございます。

長文すみません
取得されるおかしなMACアドレスですが、この現象はNetBEUIをインストールしているパソコンで発生することがわかりました。
NetBEUIによるMACアドレスを無視する方法があればぜひ教えてください。
ちなみに自分のパソコンにNetBEUIをインストールしたら同じ現象が発生しましたし、同じ日には同じ物が取得されます。
取得される値ですが、
NetBEUIなし      00-03-47-89-60-C7
NetBEUIあり      4E-39-20-52-41-53
                  00-03-47-89-60-C7
                  00-03-47-89-60-C7
                  00-03-47-89-60-C7
                  B6-EA-20-52-41-53
                  3C-58-20-52-41-53

こんな感じです。同じMACアドレスが重複して取得されるのもこの現象のひとつです。


にしの  2003-01-17 20:46:39  No: 2609

GetAdaptersInfoを使うとどうなりますか?
次のような形で使います。

lngRes := GetAdaptersInfo(nil, @lngLen);
// 戻り値lngResでエラーチェック
// ERROR_BUFFER_OVERFLOWだったらメモリを確保
AdapterMem := GetMemory(lngLen);
lngRes := GetAdaptersInfo(AdapterMem, @lngLen):
lngLenは、SizeOf(TIPAdapterInfo)の倍数になるので、複数枚のLANカードの場合は、lngLen div SizeOf(TIPAdapterInfo)が枚数になります。

// [AdaptInfo.pas]---------------------------------------------
unit AdaptInfo;

interface

uses
  Windows, Messages, SysUtils, Classes, nb30;

const
  //アダプタ名の最大長を示す定数の宣言
  MAX_ADAPTER_NAME_LENGTH = 256;
  //アダプタ説明の最大長を示す定数の宣言
  MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
  //アダプタアドレスの最大長を示す定数の宣言
  MAX_ADAPTER_ADDRESS_LENGTH = 8;
type
  PAstat = ^TAstat;
  TAstat = packed record
    adapt: TAdapterStatus;
    NameBuff: array [0 .. 29] of TNameBuffer;
  end;

  IP_ADDRESS_STRING=packed record
    IpAddressString: array[0..15] of Byte;
  end;
  IP_Mask_STRING=packed record
    IpMaskString: array[0..15] of Byte;
  end;
  IP_ADDR_STRING=packed record
    Next: Longint;
    IpAddress: IP_ADDRESS_STRING;
    IpMask: IP_MASK_STRING;
    Context: Longint;
  end;

  PIPAdapterInfo = ^TIPAdapterInfo;
  TIPAdapterInfo = packed record
    Next: LongInt;
    ComboIndex: LongInt;
    AdapterName: array[0..MAX_ADAPTER_NAME_LENGTH + 4 - 1] of Char;
    Description: array[0..MAX_ADAPTER_DESCRIPTION_LENGTH + 4 - 1] of Char;
    AddressLength: LongInt;
    Address: array[0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of Byte;
    Index: LongInt;
    lngType: LongInt;
    DhcpEnabled: LongInt;
    CurrentIpAddress: LongInt;
    IpAddressList: IP_ADDR_STRING;
    GatewayList: IP_ADDR_STRING;
    DhcpServer: IP_ADDR_STRING;
    HaveWins: LongInt;
    PrimaryWinsServer: IP_ADDR_STRING;
    SecondaryWinsServer: IP_ADDR_STRING;
    LeaseObtained: LongInt;
    LeaseExpires: LongInt;
end;

function GetAdaptersInfo(pAdapterInfo: PIPAdapterInfo; pOutBufLen: PLongInt):Longint; stdcall;

implementation

Function GetAdaptersInfo; external 'iphlpapi.dll' name 'GetAdaptersInfo';

end.
//[ここまで]---------------------------


くじら  2003-01-18 22:24:31  No: 2610

にしのさん情報ありがとうございます。

そろそろいっぱいになってきてますが、GetAdaptersInfoについて調べて頑張ってみます。
でもおかしいアドレスが取得されたら無視とかしてごまかそうかと考える弱気な自分もいますが・・・
進展がありましたらご報告させていただきます。

ありがとうございました。


HOP  2003-09-12 07:08:44  No: 2611

初めて、書きこみます。
2003/01/17(金) 11:46:39のにしのさんの書かれたGetAdaptersInfoを使ってMACアドレスを
取得しようと試みましたが、悪戦苦闘しております。

問題点その1
コンポーネントのインストールの際、次のような警告が表示される。
[警告] ユニット 'NB30' は暗黙のうちにパッケージ 'Dclusr40' に組み込まれました

問題その2
以下のコードをコンパイルしようとすると、警告を発し、無視して実行すると、
不正な処理で、落ちてしまう。

procedure TForm1.Button1Click(Sender: TObject);
var
PI:PIPAdapterInfo;
PL:PLongInt;
begin
     try
        GetAdaptersInfo(PI,PL);
     except
           ShowMessage('Error');
     end;
end;

環境:Win98SE  Delphi4Pro

どなたか、ご教授ください。宜しくお願いいたします。


にしの  2003-09-12 17:35:35  No: 2612

上に書いてあるとおり、まずは領域確保しなければなりません。

GetAdaptersInfoの引数の意味は、以下の通りです。
第1引数:PIPAdapterInfo・・・TIPAdapterInfoへのポインタ。領域があることが前提。nilが設定されると、必要なサイズを第2引数に返す。
第2引数:PLongInt・・・LongIntへのポインタ。必要なサイズを返す。領域がなければならない。

まずは、上で示すように、サイズを取得後、そのサイズの領域を確保してから、再度呼び出してください。


HOP  2003-09-13 23:05:38  No: 2613

うまくいきました。
にしのさんありがとうございました。
各プロパティーの意味を勉強します。


HOP  2003-09-15 00:08:56  No: 2614

お世話になります。
素人くさい質問で申し訳ありません。
以下のコードで、プログラム的には正常動作するように
なりました。はて、各項目の取得値の意味が飲みこめません。
MACアドレスは、どこに表示されるのでしょう。

ご教授宜しくお願いします。

AddressLength: LongInt;
    Address: array[0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of Byte;
のところだと思いますが、HEX値に変換してもAddCheckerというツール
で、取得した値と違うので、悩んでおります。

以下、コードです。

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
AdapterMem:PIPAdapterInfo;
lngRes:LongInt;
lngLen:integer;

i:integer;
STR:string;

begin
     lngRes := GetAdaptersInfo(nil, @lngLen);
     Edit1.Text:=IntToStr(lngRes);
     // 戻り値lngResでエラーチェック
     // ERROR_BUFFER_OVERFLOWだったらメモリを確保
     AdapterMem := GetMemory(lngLen);
     try
     lngRes := GetAdaptersInfo(AdapterMem, @lngLen);
     //Edit1.Text:=IntToStr(lngRes);
     Memo1.Lines.Clear;

     Memo1.Lines.Add('Next: '+IntToStr(AdapterMem.Next));
     Memo1.Lines.Add('ComboIndex: '+IntToStr(AdapterMem.ComboIndex));
     Memo1.Lines.Add('AdapterName: '+AdapterMem.AdapterName);
     Memo1.Lines.Add('Description: '+AdapterMem.Description);
     Memo1.Lines.Add('AddressLength: '+IntToStr(AdapterMem.AddressLength));

     STR:='';
     for i:=0 to 7 do
        STR:=STR+IntToStr(AdapterMem.Address[i])+' ';
     Memo1.Lines.Add('Address: '+STR);

     {
     STR:='';
     for i:=0 to 7 do
        STR:=STR+IntToHex(AdapterMem.Address[i],2)+' ';
     Memo1.Lines.Add('Address: '+STR);
     }

     Memo1.Lines.Add('Index: '+IntToStr(AdapterMem.Index));
     Memo1.Lines.Add('lngType: '+IntToStr(AdapterMem.lngType));
     Memo1.Lines.Add('DhcpEnabled: '+IntToStr(AdapterMem.DhcpEnabled));
     Memo1.Lines.Add('CurrentIpAddress: '+IntToStr(AdapterMem.CurrentIpAddress));

     //IpAddressList

     Memo1.Lines.Add('IpAddressList.Next: '+IntToStr(AdapterMem.IpAddressList.Next));

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.IpAddressList.IpAddress.IpAddressString[i])+' ';
     Memo1.Lines.Add('IpAddressList.IpAddress.IpAddressString: '+STR);

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.IpAddressList.IpMask.IpMaskString[i])+' ';
     Memo1.Lines.Add('IpAddressList.IpMask.IpMaskString: '+STR);

     Memo1.Lines.Add('IpAddressList.Context: '+IntToStr(AdapterMem.IpAddressList.Context));

     //GatewayList

     Memo1.Lines.Add('GatewayList.Next: '+IntToStr(AdapterMem.GatewayList.Next));

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.GatewayList.IpAddress.IpAddressString[i])+' ';
     Memo1.Lines.Add('GatewayList.IpAddress.IpAddressString: '+STR);

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.GatewayList.IpMask.IpMaskString[i])+' ';
     Memo1.Lines.Add('GatewayList.IpMask.IpMaskString: '+STR);

     Memo1.Lines.Add('GatewayList.Context: '+IntToStr(AdapterMem.GatewayList.Context));

     //DhcpServer

     Memo1.Lines.Add('DhcpServer.Next: '+IntToStr(AdapterMem.DhcpServer.Next));

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.DhcpServer.IpAddress.IpAddressString[i])+' ';
     Memo1.Lines.Add('DhcpServer.IpAddress.IpAddressString: '+STR);

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.DhcpServer.IpMask.IpMaskString[i])+' ';
     Memo1.Lines.Add('DhcpServer.IpMask.IpMaskString: '+STR);

     Memo1.Lines.Add('DhcpServer.Context: '+IntToStr(AdapterMem.DhcpServer.Context));

     //

     Memo1.Lines.Add('HaveWins: '+IntToStr(AdapterMem.HaveWins));

     //PrimaryWinsServer

     Memo1.Lines.Add('PrimaryWinsServer.Next: '+IntToStr(AdapterMem.PrimaryWinsServer.Next));

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.PrimaryWinsServer.IpAddress.IpAddressString[i])+' ';
     Memo1.Lines.Add('PrimaryWinsServer.IpAddress.IpAddressString: '+STR);

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.PrimaryWinsServer.IpMask.IpMaskString[i])+' ';
     Memo1.Lines.Add('PrimaryWinsServer.IpMask.IpMaskString: '+STR);

     Memo1.Lines.Add('PrimaryWinsServer.Context: '+IntToStr(AdapterMem.PrimaryWinsServer.Context));

     //SecondaryWinsServer

     Memo1.Lines.Add('SecondaryWinsServer.Next: '+IntToStr(AdapterMem.SecondaryWinsServer.Next));

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.SecondaryWinsServer.IpAddress.IpAddressString[i])+' ';
     Memo1.Lines.Add('SecondaryWinsServer.IpAddress.IpAddressString: '+STR);

     STR:='';
     for i:=0 to 15 do
        STR:=STR+IntToStr(AdapterMem.SecondaryWinsServer.IpMask.IpMaskString[i])+' ';
     Memo1.Lines.Add('SecondaryWinsServer.IpMask.IpMaskString: '+STR);

     Memo1.Lines.Add('SecondaryWinsServer.Context: '+IntToStr(AdapterMem.SecondaryWinsServer.Context));
     //

     Memo1.Lines.Add('LeaseObtained: '+IntToStr(AdapterMem.LeaseObtained));
     Memo1.Lines.Add('LeaseExpires: '+IntToStr(AdapterMem.LeaseExpires));

     except
           ShowMessage('Error');
     end;
end;

end.


にしの  2003-09-15 00:52:12  No: 2615

複数のネットワークアダプタがありませんか?

GetAdaptersInfoは、全てのネットワークアダプタの情報を返します。
このソースだと、最初の1つしか出していないようですが。


HOP  2003-09-15 06:00:43  No: 2616

にしのさんのおっしゃる通り、ダイアルアップアダプターの
情報を表示していました。

またまたの質問で、申し訳ありませんが、2枚目以降の
情報をどう取り出すのか、ご教授ください。
宜しくお願いします。


にしの  2003-09-15 06:47:33  No: 2617

上に示したTIPAdapterInfoのメンバである、
    Next: LongInt;
は、
    Next: PIPAdapterInfo
のようです。
これを辿っていけば、正しいデータが取得できると思います。

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/getadaptersinfo.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/ip_adapter_info.asp
こちらを参考にしてください。


HOP  2003-09-17 06:45:16  No: 2618

にしのさん
Nextが、Pointer to the next adapter in the list of adapters. 
ということは、次のアダプターへのポインターということは、なんとなく
理解しましたが、ではそのデータをどう拾ってくるのか、手が出ません。
ご教授ねがえませんか?


HOP  2003-09-17 18:13:30  No: 2619

スミマセン、光が見えてきました。

AdapterMem:=Pointer(AdapterMem.Next);
Memo1.Lines.Add('Description: '+AdapterMem.Description);

で、2枚目のアダプタの情報を取れました。
ただ、この処理を単体で動かすとうまくいきますが、
カード枚数分ループすると、同じ処理でも、例外で落ちてしまいます。
フー、もうひと頑張りですね。この処理方法で正しいのでしょうか?
ご教授いただけませんか?


にしの  2003-09-17 18:40:41  No: 2620

OKですよ。

Memo1.Lines.Clear;
の後、
// AdapterMemに実体へのポインタが入っているはず。
// 入っていなければnil。
while AdapterMem <> nil do
begin
  // メモへ情報を追加
  // (省略)
  // ループの最後で次の実体へのポインタを取得。最後であればnilが返ってくる
  AdapterMem:=Pointer(AdapterMem.Next);
end;
こんな感じです。
よくある単方向リストです。


HOP  2003-09-18 09:17:48  No: 2621

やっと,解説に通りにうまくいきました。
ありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加