/ ======================================================================
//返回值是主机AServerName的MAC地址
//AServerName参数的格式为'\\ServerName' 或者 'ServerName'
//参数ServerName为空时返回本机的MAC地址
//MAC地址以'XX-XX-XX-XX-XX-XX'的格式返回
// ======================================================================function GetMacAddress(const AServerName: string): string;
type
TNetTransportEnum = function(pszServer: PWideChar;
Level: DWORD;
var pbBuffer: pointer;
PrefMaxLen: LongInt;
var EntriesRead: DWORD;
var TotalEntries: DWORD;
var ResumeHandle: DWORD): DWORD; stdcall; TNetApiBufferFree = function(Buffer: pointer): DWORD; stdcall; PTransportInfo = ^TTransportInfo;
TTransportInfo = record
quality_of_service: DWORD;
number_of_vcs: DWORD;
transport_name: PWChar;
transport_address: PWChar;
wan_ish: boolean;
end;var
E, ResumeHandle,
EntriesRead,
TotalEntries: DWORD;
FLibHandle: THandle;
sMachineName,
sMacAddr,
Retvar: string;
pBuffer: pointer;
pInfo: PTransportInfo;
FNetTransportEnum: TNetTransportEnum;
FNetApiBufferFree: TNetApiBufferFree;
pszServer: array[0..128] of WideChar;
i, ii, iIdx: integer;
begin
sMachineName := trim(AServerName);
Retvar := '00-00-00-00-00-00'; // Add leading \\ if missing
if (sMachineName <> '') and (length(sMachineName) >= 2) then
begin
if copy(sMachineName, 1, 2) <> '\\' then
sMachineName := '\\' + sMachineName
end; // Setup and load from DLL
pBuffer := nil;
ResumeHandle := 0;
FLibHandle := LoadLibrary('NETAPI32.DLL'); // Execute the external function
if FLibHandle <> 0 then
begin
@FNetTransportEnum := GetProcAddress(FLibHandle, 'NetWkstaTransportEnum');
@FNetApiBufferFree := GetProcAddress(FLibHandle, 'NetApiBufferFree');
E := FNetTransportEnum(StringToWideChar(sMachineName, pszServer, 129), 0,
pBuffer, -1, EntriesRead, TotalEntries, Resumehandle); if E = 0 then
begin
pInfo := pBuffer; // Enumerate all protocols - look for TCPIP
for i := 1 to EntriesRead do
begin
if pos('TCPIP', UpperCase(pInfo^.transport_name)) <> 0 then
begin
// Got It - now format result 'xx-xx-xx-xx-xx-xx'
iIdx := 1;
sMacAddr := pInfo^.transport_address; for ii := 1 to 12 do
begin
Retvar[iIdx] := sMacAddr[ii];
inc(iIdx);
if iIdx in [3, 6, 9, 12, 15] then inc(iIdx);
end;
end; inc(pInfo);
end;
if pBuffer <> nil then FNetApiBufferFree(pBuffer);
end; try
FreeLibrary(FLibHandle);
except
// 错误处理
end;
end;
result := Retvar;
end;
//返回值是主机AServerName的MAC地址
//AServerName参数的格式为'\\ServerName' 或者 'ServerName'
//参数ServerName为空时返回本机的MAC地址
//MAC地址以'XX-XX-XX-XX-XX-XX'的格式返回
// ======================================================================function GetMacAddress(const AServerName: string): string;
type
TNetTransportEnum = function(pszServer: PWideChar;
Level: DWORD;
var pbBuffer: pointer;
PrefMaxLen: LongInt;
var EntriesRead: DWORD;
var TotalEntries: DWORD;
var ResumeHandle: DWORD): DWORD; stdcall; TNetApiBufferFree = function(Buffer: pointer): DWORD; stdcall; PTransportInfo = ^TTransportInfo;
TTransportInfo = record
quality_of_service: DWORD;
number_of_vcs: DWORD;
transport_name: PWChar;
transport_address: PWChar;
wan_ish: boolean;
end;var
E, ResumeHandle,
EntriesRead,
TotalEntries: DWORD;
FLibHandle: THandle;
sMachineName,
sMacAddr,
Retvar: string;
pBuffer: pointer;
pInfo: PTransportInfo;
FNetTransportEnum: TNetTransportEnum;
FNetApiBufferFree: TNetApiBufferFree;
pszServer: array[0..128] of WideChar;
i, ii, iIdx: integer;
begin
sMachineName := trim(AServerName);
Retvar := '00-00-00-00-00-00'; // Add leading \\ if missing
if (sMachineName <> '') and (length(sMachineName) >= 2) then
begin
if copy(sMachineName, 1, 2) <> '\\' then
sMachineName := '\\' + sMachineName
end; // Setup and load from DLL
pBuffer := nil;
ResumeHandle := 0;
FLibHandle := LoadLibrary('NETAPI32.DLL'); // Execute the external function
if FLibHandle <> 0 then
begin
@FNetTransportEnum := GetProcAddress(FLibHandle, 'NetWkstaTransportEnum');
@FNetApiBufferFree := GetProcAddress(FLibHandle, 'NetApiBufferFree');
E := FNetTransportEnum(StringToWideChar(sMachineName, pszServer, 129), 0,
pBuffer, -1, EntriesRead, TotalEntries, Resumehandle); if E = 0 then
begin
pInfo := pBuffer; // Enumerate all protocols - look for TCPIP
for i := 1 to EntriesRead do
begin
if pos('TCPIP', UpperCase(pInfo^.transport_name)) <> 0 then
begin
// Got It - now format result 'xx-xx-xx-xx-xx-xx'
iIdx := 1;
sMacAddr := pInfo^.transport_address; for ii := 1 to 12 do
begin
Retvar[iIdx] := sMacAddr[ii];
inc(iIdx);
if iIdx in [3, 6, 9, 12, 15] then inc(iIdx);
end;
end; inc(pInfo);
end;
if pBuffer <> nil then FNetApiBufferFree(pBuffer);
end; try
FreeLibrary(FLibHandle);
except
// 错误处理
end;
end;
result := Retvar;
end;
解决方案 »
- delphi+ado+access 日期函数
- delphi7能调用mysql数据库吗
- 如何将word模板文件放入资源文件中,又如何从资源文件中提取这个模板文件?
- 有没有这样的用法哟
- 打算编写一个搜索邮件地址的软件,不知有没有钱图?
- 我用wise9.01打包程序,出现“无法生成系统配置文件,请以管理员身份登录重新安装”这是为什么?
- 图像显示中出现白线,请教这是什么原因.
- 俺用 Wininet 设置了SSL证书,为什么还是返回 False
- adodataset插记录的报错?
- 如何在Delphi中得到所有的错误
- 有没有可以放Delphi软件的便携式数据采集工具呢?
- 高手们··如何在select语句中加入一个排序列???急!!!!!!!!!
E := FNetTransportEnum(StringToWideChar(sMachineName, pszServer, 129), 0,
pBuffer, -1, EntriesRead, TotalEntries, Resumehandle);这个返回的值的作用我用这段代码能够得到本机的mac地址,但是不能得到远程机器的mac地址,请问有其他更好的办法吗?
interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock,
StdCtrls;const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 6767; //设定UDP端口号
NBTPORT = 137;type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
s: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
procedure ReadData(var Message: TMessage); message WM_SOCK;
public
{ Public declarations }
procedure SendData(b:array of byte); procedure GetInfo(buffer: Array of byte;len:integer);
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
var
TempWSAData: TWSAData;
//optval: integer;
begin
// 初始化SOCKET
if WSAStartup($101, TempWSAData)=1 then
showmessage('StartUp Error!'); s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(s);
end;
//本机SockAddr绑定
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := INADDR_ANY;
addr.sin_port := htons(UDPPORT);
if Bind(s, addr, sizeof(addr)) <> 0 then
begin
showmessage('bind fail');
end;
WSAAsyncSelect(s, Form1.Handle , WM_SOCK, FD_READ);
//对方SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);
end;procedure TForm1.GetInfo(buffer: Array of byte;len:integer);
var
str:string;
i,j,pos,name_num: integer;
begin name_num:=0;
for i:=1 to len do
begin
if((buffer[i]=$21)and(buffer[i+1]=$00)and(buffer[i+2]=$01))
then
begin
name_num:=buffer[i+9];
break;
end;
end;
if name_num=0 then exit;
pos:=i+10; str:='';
for i:=pos to (pos+18*name_num-1) do
begin
if (((i-pos)mod 18) =0) then
begin
for j:=0 to 14 do
begin
if trim(char(buffer[i+j]))='' then buffer[i+j]:=ord(' ');
str:=str+char(buffer[i+j]);
end;
if (buffer[i+16] and $80)=$80 then
begin
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<GROUP>';
ListBox1.Items.Add(str);
end
else
begin
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<UNIQUE>';
ListBox1.Items.Add(str);
end;
str:='';
end;
end; for i:=0 to 5 do
begin
str:=str+format('%.2x.',[buffer[i+pos+18*name_num]]);
end;
delete(str,length(str),1);
str:='MAC:'+str;
ListBox1.Items.Add(str);
ListBox1.Items.Add('------------------------------------------------------');
ListBox1.TopIndex :=ListBox1.Items.count-1;end;procedure TForm1.ReadData(var Message: TMessage);
var
buffer: Array [1..500] of byte;
len{,i}: integer;
flen: integer;
Event: word;
value: string;begin
value:='';
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(NBTPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
{for i:=1 to len do value:=value+format('%x',[buffer[i]]);
ListBox1.items.add(value);
value:='';
for i:=1 to len do if char(buffer[i])<>#0 then value:=value+char(buffer[i]);
ListBox1.items.add(value);}
if len<> 0 then GetInfo(buffer,len);
end;
end;procedure TForm1.SendData(b:array of byte);
var
len: integer;
begin FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(edit1.text));
len := sendto(s, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
//if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then showmessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then
showmessage('send fail');
if len <> 50 then
showmessage('Not Send all');
end;procedure TForm1.Button1Click(Sender: TObject);
const NbtstatPacket:array[0..49]of byte
=($0,$0,$0,$10,$0,$1,
$0,$0,$0,$0,$0,$0,$20,$43,$4b,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$41,$41,
$41,$41,$41,$41,$41,$41,$0,$0,$21,$0,$1);
begin senddata(NbtstatPacket);end;end.窗口加这三个控件:TButton;TListBox;TEdit; Button1: TButton; ListBox1: TListBox; Edit1: TEdit;联上3个过程:
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
var PhyAddrLen: DWORD): DWORD;
stdcall; external 'IPHlpAPI.DLL';function GetRemoteMACAddress(DestIP: string): string;
type
TInfo = array[0..7] of BYTE;
var
dwTargetIP: DWORD;
dwMacAddress: array[0..1] of DWORD;
dwMacLen: DWORD;
dwResult: DWORD;
X: TInfo;
begin
dwTargetIP := Inet_Addr(PChar(DestIP));
dwMacLen := 6;
dwResult := SendARP(dwTargetIP, 0, @dwMacAddress[0], dwMacLen);
if dwResult = NO_ERROR then
begin
X := TInfo(dwMacAddress);
Result := Format('%x%x%x%x%x%x',
[X[0], X[1], X[2], X[3], X[4], X[5]]);
end;
end;
http://search.csdn.net/Expert/topic/683/683119.xml?temp=.9414026
No special group membership is required to successfully execute NetWkstaTransportEnum.NET_API_STATUS NetWkstaTransportEnum(
LPWSTR servername,
DWORD level,
LPBYTE *bufptr,
DWORD prefmaxlen,
LPDWORD entriesread,
LPDWORD totalentries,
LPDWORD resumehandle
);
Parameters
servername
Ppointer to a Unicode string containing the name of the remote server on which the function is to execute. A NULL pointer or string specifies the local computer.
level
Specifies the following value to return the level of information provided. Value Meaning
0 The bufptr parameter points to a WKSTA_TRANSPORT_INFO_0 structure.
bufptr
On return a pointer to the return information structure is returned in the address pointed to by bufptr.
prefmaxlen
Preferred maximum length, in 8-bit bytes of returned data.
entriesread
Pointer to a DWORD that contains the actual enumerated element count.
totalentries
Pointer to a DWORD that contains the total number of entries that could have been enumerated from the current resume position.
resumehandle
Pointer to a DWORD that contains resumehandle, which is used to continue an existing workstation transport search. The handle should be zero on the first call and left unchanged for subsequent calls. If resumehandle is NULL, no resume handle is stored.
Return Values
If the function is successful, it returns NERR_SUCCESS.If the function fails, the return value is one of the following error codes.Value Meaning
ERROR_MORE_DATA Additional information is available.
ERROR_INVALID_LEVEL The level parameter, which indicates what level of data structure information is available, is invalid.
但这个仍然不能解决我的问题!
你想查詢指定計算機的信息就可用這個函數
返回的值, 告訴你這個函數執行成功與否, 如果是:
NERR_Success 就是執行成功了, 如果是:
ERROR_MORE_DATA 就是你的緩衝區不夠大ERROR_INVALID_LEVEL 你的level 設置有問題
你的第二段代码能够得到本网段内机器的MAC地址,但是对于通过路由器的外网段机器无法的到!
怎么回事?
ksaiy(消失在人海-喜欢昆明的花) ( ) 信誉:100 你可以加我吗?
以后我可以向您请教问题!
可惜!
http://www.delphibox.com/article.asp?articleid=327 局域网搜索软件。方便快捷地搜索、浏览局域网资源。多线程搜索局域网上所有的工作组、主机、打印机、共享文件。自动搜索所有共享的mp3、电影或自定义搜索的文件;允许用户自己设置登录的用户名密码。包括默认值和对不同的主机设置不同的值;内置nbtstat,能快速查找某一IP网段内的所有主机,并根据IP地址得到对方主机的主机名、工作组名、用户名、MAC地址,速度极快。并方便地访问其资源。能对某一地址范围的主机进行ping,端口扫描操作,找出所有的WEB服务器,FTP服务器等。能向某一主机发送消息。提供断点续传的功能(局域网机器间拷贝文件时)。