こんにちわ、くじらと申します。
こちらの過去ログのWindows2000でMACアドレスを取得する方法をやってみたのですが、おかしなMACアドレスが取得されてしまいます。
ipconfigで確認しても表示されない物で、明らかに使用していないMACアドレスです。
現象は
・毎日取得すると毎日違う物が取得される
・全てのパソコンでこの現象が発生するわけではない
なにか原因と思われることがあれば教えてください。
コードは過去ログのものをそのままで試してもダメでした。
あいまいな質問ですいませんがよろしくお願いします。
過去ログというと、私が回答した
https://www.petitmonte.com/bbs/answers?question_id=84
だと思いますが、うまくいかないというのは、このコードまるまる使ってもだめということでしょうか。
# 空白を全角にしてあるので半角スペース2つに置き換える必要があります
XPではうまく動いているのですが。
毎日違うということは、同じ日なら同じものが取得されるということでしょうか。
にしのさんレスありがとうございます。
長文すみません
取得されるおかしな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アドレスが重複して取得されるのもこの現象のひとつです。
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.
//[ここまで]---------------------------
にしのさん情報ありがとうございます。
そろそろいっぱいになってきてますが、GetAdaptersInfoについて調べて頑張ってみます。
でもおかしいアドレスが取得されたら無視とかしてごまかそうかと考える弱気な自分もいますが・・・
進展がありましたらご報告させていただきます。
ありがとうございました。
初めて、書きこみます。
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
どなたか、ご教授ください。宜しくお願いいたします。
上に書いてあるとおり、まずは領域確保しなければなりません。
GetAdaptersInfoの引数の意味は、以下の通りです。
第1引数:PIPAdapterInfo・・・TIPAdapterInfoへのポインタ。領域があることが前提。nilが設定されると、必要なサイズを第2引数に返す。
第2引数:PLongInt・・・LongIntへのポインタ。必要なサイズを返す。領域がなければならない。
まずは、上で示すように、サイズを取得後、そのサイズの領域を確保してから、再度呼び出してください。
うまくいきました。
にしのさんありがとうございました。
各プロパティーの意味を勉強します。
お世話になります。
素人くさい質問で申し訳ありません。
以下のコードで、プログラム的には正常動作するように
なりました。はて、各項目の取得値の意味が飲みこめません。
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.
複数のネットワークアダプタがありませんか?
GetAdaptersInfoは、全てのネットワークアダプタの情報を返します。
このソースだと、最初の1つしか出していないようですが。
にしのさんのおっしゃる通り、ダイアルアップアダプターの
情報を表示していました。
またまたの質問で、申し訳ありませんが、2枚目以降の
情報をどう取り出すのか、ご教授ください。
宜しくお願いします。
上に示した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
こちらを参考にしてください。
にしのさん
Nextが、Pointer to the next adapter in the list of adapters.
ということは、次のアダプターへのポインターということは、なんとなく
理解しましたが、ではそのデータをどう拾ってくるのか、手が出ません。
ご教授ねがえませんか?
スミマセン、光が見えてきました。
AdapterMem:=Pointer(AdapterMem.Next);
Memo1.Lines.Add('Description: '+AdapterMem.Description);
で、2枚目のアダプタの情報を取れました。
ただ、この処理を単体で動かすとうまくいきますが、
カード枚数分ループすると、同じ処理でも、例外で落ちてしまいます。
フー、もうひと頑張りですね。この処理方法で正しいのでしょうか?
ご教授いただけませんか?
OKですよ。
Memo1.Lines.Clear;
の後、
// AdapterMemに実体へのポインタが入っているはず。
// 入っていなければnil。
while AdapterMem <> nil do
begin
// メモへ情報を追加
// (省略)
// ループの最後で次の実体へのポインタを取得。最後であればnilが返ってくる
AdapterMem:=Pointer(AdapterMem.Next);
end;
こんな感じです。
よくある単方向リストです。
やっと,解説に通りにうまくいきました。
ありがとうございます。
ツイート | ![]() |