J
james_liang
Unregistered / Unconfirmed
GUEST, unregistred user!
我要写一个将IP地址转换为MAC地址(网卡硬件地址)的DLL.但是如果我不加红色代码部分 showmessage('sdfsdf'); 这一句,
则procedure Tformmain.ReadData(var Message: TMessage);不会执行.(结果得不到真正的MAC地址)
我不想要这个信息框出现.谁能告诉我怎么改?
//****************************
//DLL部分
library pj003;
uses
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
Forms,
Variants,
Dialogs,
winsock,
StdCtrls,
ExtCtrls,
ComCtrls;
const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 6767; //设定UDP端口号
NBTPORT = 137;
type
Tformmain = class(TForm)
procedure ReadData(var Message: TMessage); message WM_SOCK;
procedure RecvNbMsg(buffer: Array of byte;len:integer;IP:string);
procedure SendData(b:array of byte;IP:string);
end;
var
IP,IP2:string;
B1,B2: array [0..3]of byte;
frmmain1: Tformmain;
WAIT_ACK_EVENT: Thandle;
wait_time: integer;
MacAddr:String;
s: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
function IsLegalIP(IP:string):boolean;
begin
if Longword(inet_addr(pchar(IP)))=INADDR_NONE then
begin
result:=false;
exit;
end
else
result:=true;
end;
procedure GetAddrByte(IP:string;var B:array of byte);
var i,j:integer;
s:string;
begin
s:='';
j:=0;
IP:=IP+'.';
for i:=1 to length(IP)do
begin
if IP<>'.' then s:=s+IP
else
begin
B[j]:=byte(strtoint(s));
inc(j);
s:='';
end;
end;
end;
procedure Tformmain.SendData(b:array of byte;IP:string);
var
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(IP));
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
len := sendto(s, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
//if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then //showmessage(inttostr(WSAGetLastError()));
if (len = SOCKET_ERROR) or (len <> 50) then MacAddr:='4';
[red] showmessage('sdfsdf');[/red]
end;
procedure Send;
const NbtstatPacket:array[0..49]of byte
=($0,$0,$0,$0,$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
frmmain1.senddata(NbtstatPacket,IP);
end;
procedure Tformmain.RecvNbMsg(buffer: Array of byte;len:integer;IP:string);
var
str:string;
i,j,pos,name_num: integer;
begin
name_num:=0;
for i:=1 to len do
begin
if((buffer=$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>';
end
else
begin
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<UNIQUE>';
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);
MacAddr:=str; //Mac
end;
procedure Tformmain.ReadData(var Message: TMessage);
var
buffer: Array [1..500] of byte;
flen,len: integer;
Event: word;
IP:string;
begin
showmessage('123');
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
if len> 0 then
begin
//FSockAddrIn.sin_addr.S_un_b.s_b1
with FSockAddrIn.sin_addr.S_un_b
do IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]);
RecvNbMsg(buffer,len,IP);
end;
SetEvent(WAIT_ACK_EVENT);
end;
end;
Function IptoMac(text:String):String; stdcall;
var
TempWSAData: TWSAData;
begin
MacAddr:='' ;
frmmain1:=Tformmain.CreateNew(Application);
// 初始化SOCKET
if WSAStartup($101, TempWSAData)=1 then
MacAddr:='0'; //showmessage('StartUp Error!');
s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
MacAddr:='1'; // 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
MacAddr:='2'; //showmessage('bind fail');
end;
WSAAsyncSelect(s, frmmain1.Handle , WM_SOCK, FD_READ);
//对方SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
WAIT_ACK_EVENT:=CreateEvent(nil,true,false,pchar('WAIT_ACK'));
//ResetEvent(WAIT_ACK_EVENT);
wait_time:=100;
IP :=Text;
// IP2 :=Text;
if (not IsLegalIP(IP))or(not IsLegalIP(IP2)) then
begin
MacAddr:='3';//showmessage('Illegal IP address!');
exit;
end;
GetAddrByte(IP,B1);
// GetAddrByte(IP2,B2);
IP:=format('%d.%d.%d.%d',[B1[0],B1[1],B1[2],B1[3]]);
Send;
waitforsingleobject(WAIT_ACK_EVENT,wait_time);
ResetEvent(WAIT_ACK_EVENT);
CloseSocket(s);
frmmain1.Free ;
Result :=macaddr;
end;
exports
IptoMac;
begin
end.
//****************************
//EXE文件调用部分
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button2: TButton;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
function IptoMac(text:string):string;stdcall external 'pj003.dll';
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
showmessage(iptomac('192.168.0.2'));
end;
end.
则procedure Tformmain.ReadData(var Message: TMessage);不会执行.(结果得不到真正的MAC地址)
我不想要这个信息框出现.谁能告诉我怎么改?
//****************************
//DLL部分
library pj003;
uses
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
Forms,
Variants,
Dialogs,
winsock,
StdCtrls,
ExtCtrls,
ComCtrls;
const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 6767; //设定UDP端口号
NBTPORT = 137;
type
Tformmain = class(TForm)
procedure ReadData(var Message: TMessage); message WM_SOCK;
procedure RecvNbMsg(buffer: Array of byte;len:integer;IP:string);
procedure SendData(b:array of byte;IP:string);
end;
var
IP,IP2:string;
B1,B2: array [0..3]of byte;
frmmain1: Tformmain;
WAIT_ACK_EVENT: Thandle;
wait_time: integer;
MacAddr:String;
s: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn; //利用消息实时获知UDP消息
function IsLegalIP(IP:string):boolean;
begin
if Longword(inet_addr(pchar(IP)))=INADDR_NONE then
begin
result:=false;
exit;
end
else
result:=true;
end;
procedure GetAddrByte(IP:string;var B:array of byte);
var i,j:integer;
s:string;
begin
s:='';
j:=0;
IP:=IP+'.';
for i:=1 to length(IP)do
begin
if IP<>'.' then s:=s+IP
else
begin
B[j]:=byte(strtoint(s));
inc(j);
s:='';
end;
end;
end;
procedure Tformmain.SendData(b:array of byte;IP:string);
var
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(IP));
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
len := sendto(s, b[0],50, 0, FSockAddrIn, sizeof(FSockAddrIn));
//if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then //showmessage(inttostr(WSAGetLastError()));
if (len = SOCKET_ERROR) or (len <> 50) then MacAddr:='4';
[red] showmessage('sdfsdf');[/red]
end;
procedure Send;
const NbtstatPacket:array[0..49]of byte
=($0,$0,$0,$0,$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
frmmain1.senddata(NbtstatPacket,IP);
end;
procedure Tformmain.RecvNbMsg(buffer: Array of byte;len:integer;IP:string);
var
str:string;
i,j,pos,name_num: integer;
begin
name_num:=0;
for i:=1 to len do
begin
if((buffer=$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>';
end
else
begin
str:=str+format('<%x>',[buffer[i+15]]);
str:=str+'<UNIQUE>';
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);
MacAddr:=str; //Mac
end;
procedure Tformmain.ReadData(var Message: TMessage);
var
buffer: Array [1..500] of byte;
flen,len: integer;
Event: word;
IP:string;
begin
showmessage('123');
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
if len> 0 then
begin
//FSockAddrIn.sin_addr.S_un_b.s_b1
with FSockAddrIn.sin_addr.S_un_b
do IP:=format('%d.%d.%d.%d',[ord(s_b1),ord(s_b2),ord(s_b3),ord(s_b4)]);
RecvNbMsg(buffer,len,IP);
end;
SetEvent(WAIT_ACK_EVENT);
end;
end;
Function IptoMac(text:String):String; stdcall;
var
TempWSAData: TWSAData;
begin
MacAddr:='' ;
frmmain1:=Tformmain.CreateNew(Application);
// 初始化SOCKET
if WSAStartup($101, TempWSAData)=1 then
MacAddr:='0'; //showmessage('StartUp Error!');
s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
MacAddr:='1'; // 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
MacAddr:='2'; //showmessage('bind fail');
end;
WSAAsyncSelect(s, frmmain1.Handle , WM_SOCK, FD_READ);
//对方SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(NBTPORT);
WAIT_ACK_EVENT:=CreateEvent(nil,true,false,pchar('WAIT_ACK'));
//ResetEvent(WAIT_ACK_EVENT);
wait_time:=100;
IP :=Text;
// IP2 :=Text;
if (not IsLegalIP(IP))or(not IsLegalIP(IP2)) then
begin
MacAddr:='3';//showmessage('Illegal IP address!');
exit;
end;
GetAddrByte(IP,B1);
// GetAddrByte(IP2,B2);
IP:=format('%d.%d.%d.%d',[B1[0],B1[1],B1[2],B1[3]]);
Send;
waitforsingleobject(WAIT_ACK_EVENT,wait_time);
ResetEvent(WAIT_ACK_EVENT);
CloseSocket(s);
frmmain1.Free ;
Result :=macaddr;
end;
exports
IptoMac;
begin
end.
//****************************
//EXE文件调用部分
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button2: TButton;
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
function IptoMac(text:string):string;stdcall external 'pj003.dll';
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
showmessage(iptomac('192.168.0.2'));
end;
end.