您的位置:程序门 -> delphi -> windows sdk/api



如何截获网卡的“启用/禁用连接”的事件?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


如何截获网卡的“启用/禁用连接”的事件?
发表于:2008-01-13 17:53:02 楼主
如何截获网卡的   启用/禁用连接   的事件?
不知道钩子可以实现吗?   如果可以,   要用哪种类型的钩子?   哪个消息?
或者有其他方法?
发表于:2008-01-14 09:45:451楼 得分:0
try   wmi   ndis   events  
发表于:2008-01-14 10:14:172楼 得分:0
you   need   wmi   events.   wmi   subsystem   fires   them   when   the   state   of   plug&play   devices   change.  
you   can   register   for   wmi   events   using   wql   query.  
for   example,  

select   *   from   __instancecreateevent  
within   5  
where   targetinstance   isa   "xx   device"
发表于:2008-01-14 10:39:443楼 得分:0
对于你所要的,那就\root\wmi:
select   *   from   msndis_statusmediadisconnect
select   *   from   msndis_statusmediaconnect
发表于:2008-01-14 11:15:024楼 得分:0
unit   adputils;

interface

uses   windows;

const
    max_interface_name_len   =   256;
    maxlen_physaddr   =   8;
    maxlen_ifdescr   =   256;
    mib_if_type_other   =   1;
    mib_if_type_ethernet   =   6;
    mib_if_type_tokenring   =   9;
    mib_if_type_fddi   =   15;
    mib_if_type_ppp   =   23;
    mib_if_type_loopback   =   24;
    mib_if_type_slip   =   28;
    mib_if_admin_status_up   =   1;
    mib_if_admin_status_down   =   2;
    mib_if_admin_status_testing   =   3;
    mib_if_oper_status_non_operational   =   0;
    mib_if_oper_status_unreachable   =   1;
    mib_if_oper_status_disconnected   =   2;
    mib_if_oper_status_connecting   =   3;
    mib_if_oper_status_connected   =   4;
    mib_if_oper_status_operational   =   5;

type
    mib_physaddr   =   array[0..maxlen_physaddr   -   1]   of   byte;
    mib_ifdescr   =   array[0..maxlen_ifdescr   -   1]   of   char;

    pmib_ifrow   =   ^mib_ifrow;
    mib_ifrow   =   packed   record
        wszname:   array[0..max_interface_name_len   -   1]   of   wchar;
        dwindex,
        dwtype,
        dwmtu,
        dwspeed,
        dwphysaddrlen:   dword;
        bphysaddr:   mib_physaddr;
        dwadminstatus,
        dwoperstatus,
        dwlastchange,
        dwinoctets,
        dwinucastpkts,
        dwinnucastpkts,
        dwindiscards,
        dwinerrors,
        dwinunknownprotos,
        dwoutoctets,
        dwoutucastpkts,
        dwoutnucastpkts,
        dwoutdiscards,
        dwouterrors,
        dwoutqlen,
        dwdescrlen:   dword;
        bdescr:   mib_ifdescr;
    end;

    pmib_iftable   =   ^mib_iftable;
    mib_iftable   =   packed   record
        dwnumentries:   dword;
        table:   array[0..0]   of   mib_ifrow;
    end;

    tadapterstatus   =   record
        dwtype,
        dwoperstatus:   dword;
        bdescr:   mib_ifdescr;
    end;
    tadapterstatuses   =   array   of   tadapterstatus;

function   getiftable(piftable:   pmib_iftable;   pdwsize:   pulong;   border:   bool):   dword;
    stdcall;   external   'iphlpapi.dll';
function   getadaptertypestring(const   dwtype:   dword):   string;
function   getgetadapterstatusstring(const   dwoperstatus:   dword):   string;
procedure   scanadapters(var   adapterstatuses:   tadapterstatuses);

implementation

var
    dwsize:   dword;
    pmibiftable:   pmib_iftable;

function   getadaptertypestring(const   dwtype:   dword):   string;
begin
    case   dwtype   of
        mib_if_type_other:   result   :=   '其他';
        mib_if_type_ethernet:   result   :=   '以太网';
        mib_if_type_tokenring:   result   :=   '令牌环';
        mib_if_type_fddi:   result   :=   'fddi';
        mib_if_type_ppp:   result   :=   'ppp';
        mib_if_type_loopback:   result   :=   '回路';
        mib_if_type_slip:   result   :=   'slip';
    end;
end;

function   getgetadapterstatusstring(const   dwoperstatus:   dword):   string;
begin
    case   dwoperstatus   of
        mib_if_oper_status_non_operational:   result   :=   '掉线';
        mib_if_oper_status_unreachable:   result   :=   '不可达';
        mib_if_oper_status_disconnected:   result   :=   '断开';
        mib_if_oper_status_connecting:   result   :=   '连接中';
        mib_if_oper_status_connected:   result   :=   '已连接';
        mib_if_oper_status_operational:   result   :=   '连通';
    end;
end;

procedure   scanadapters(var   adapterstatuses:   tadapterstatuses);
var
    dwretval:   dword;
    num,   i:   longint;
begin
    dwretval   :=   getiftable(pmibiftable,   @dwsize,   false);
    if   dwretval   =   no_error   then
    begin
        num   :=   pmibiftable^.dwnumentries;
        if   length(adapterstatuses)   <>   num   then
            setlength(adapterstatuses,   num);
        for   i   :=   low(adapterstatuses)   to   high(adapterstatuses)   do
        begin
            adapterstatuses[i].dwtype   :=   pmibiftable^.table[i].dwtype;
            adapterstatuses[i].dwoperstatus   :=   pmibiftable^.table[i].dwoperstatus;
            adapterstatuses[i].bdescr   :=   pmibiftable^.table[i].bdescr;
        end;
    end;
end;

initialization
    getiftable(nil,   @dwsize,   false);
    getmem(pmibiftable,   dwsize);
   
finalization
    freemem(pmibiftable);

end.


unit   mainform;

interface

uses
    classes,   controls,   forms,   extctrls,   comctrls,   adputils;

type
    tfrmmain   =   class(tform)
        tmrefresh:   ttimer;
        lvadapters:   tlistview;
        procedure   tmrefreshtimer(sender:   tobject);
    private
        fadapterstatuses:   tadapterstatuses;
        fadapternum:   integer;
        procedure   refreshadapterstatuses;
    public
        {   public   declarations   }
    end;

var
    frmmain:   tfrmmain;

implementation

{$r   *.dfm}

procedure   tfrmmain.refreshadapterstatuses;
var
    num,   i:   integer;
begin
    scanadapters(fadapterstatuses);
    num   :=   length(fadapterstatuses);
    if   num   =   fadapternum   then
    begin
        for   i   :=   0   to   num   -   1   do
            lvadapters.items[i].subitems[1]   :=   getgetadapterstatusstring(fadapterstatuses[i].dwoperstatus);
    end
    else   begin
        lvadapters.items.beginupdate;
        lvadapters.items.clear;
        for   i   :=   0   to   num   -   1   do
        begin
            lvadapters.items.add;
            lvadapters.items[i].caption   :=   getadaptertypestring(fadapterstatuses[i].dwtype);
            lvadapters.items[i].subitems.add(fadapterstatuses[i].bdescr);
            lvadapters.items[i].subitems.add(getgetadapterstatusstring(fadapterstatuses[i].dwoperstatus));
        end;
        lvadapters.items.endupdate;
        fadapternum   :=   num;
    end;
end;

procedure   tfrmmain.tmrefreshtimer(sender:   tobject);
begin
    refreshadapterstatuses;
end;

end.
发表于:2008-01-16 22:41:455楼 得分:0
mark!
发表于:2008-01-17 11:01:396楼 得分:0
非常不错.
发表于:2008-01-17 11:30:397楼 得分:0
const      
                discverb       =       '禁用(&b)';      
                connverb       =       '启用(&a)';      
       
    function       disableethernet(const       ethname:       string):       boolean;      
    var      
            cpfolder:       folder;      
            nwfolder:       folder;      
            nverbs:       folderitemverbs;          
            i,j,k:       integer;      
    begin      
            result       :=       false;      
            cpfolder       :=       shell1.namespace(3);      
            if       cpfolder       <>       nil       then      
            begin      
                    for       i       :=       0       to       cpfolder.items.count-1       do      
                    begin      
                            if       cpfolder.items.item(i).name       =       '网络和拨号连接'       then      
                            begin      
                                    nwfolder       :=       cpfolder.items.item(i).getfolder       as       folder;      
                                    if       nwfolder       <>       nil       then      
                                    begin      
                                            for       j       :=0       to       nwfolder.items.count-1       do      
                                            begin      
                                                    if       nwfolder.items.item(j).name       =       ethname       then      
                                                    begin      
                                                            nverbs       :=       nwfolder.items.item(j).verbs;      
                                                            for       k       :=       0       to           nverbs.count-1       do      
                                    begin      
                                                                    if       nverbs.item(k).name       =       discverb       then      
                                                                    begin      
                                                                            nverbs.item(k).doit;              
                                                                            result       :=       true;      
                                                                    end;      
                                                            end;      
                                                    end;      
                                            end;      
                                    end;      
                            end;      
                    end;      
                    if       nwfolder       =       nil       then      
                                showmessage('network       and       dial-up       connections       not       found');      
            end      
            else      
                    showmessage('control       panel       not       found');      
       
    end;      
       
       
    function       enableethernet(const       ethname:       string):       boolean;      
    var      
            cpfolder:       folder;      
            nwfolder:       folder;      
            nverbs:       folderitemverbs;          
            i,j,k:       integer;      
    begin      
            result       :=       false;      
            cpfolder       :=       shell1.namespace(3);      
            if       cpfolder       <>       nil       then      
            begin      
                    for       i       :=       0       to       cpfolder.items.count-1       do      
                    begin      
                            if       cpfolder.items.item(i).name       =       '网络和拨号连接'       then      
                            begin      
                                    nwfolder       :=       cpfolder.items.item(i).getfolder       as       folder;      
                                    if       nwfolder       <>       nil       then      
                                    begin      
                                            for       j       :=0       to       nwfolder.items.count-1       do      
                                            begin      
                                                    if       nwfolder.items.item(j).name       =       ethname       then      
                                                    begin      
                                                            nverbs       :=       nwfolder.items.item(j).verbs;      
                                                            for       k       :=       0       to           nverbs.count-1       do      
                                    begin      
                                                                    if       nverbs.item(k).name       =       connverb       then      
                                                                    begin      
                                                                            nverbs.item(k).doit;              
                                                                            result       :=       true;      
                                                                    end;      
                                                            end;      
                                                    end;      
                                            end;      
                                    end;      
                            end;      
                    end;      
                    if       nwfolder       =       nil       then      
                                showmessage('network       and       dial-up       connections       not       found');      
            end      
            else      
                    showmessage('control       panel       not       found');      
    end;      
发表于:2008-01-22 17:02:148楼 得分:0
非常感谢大家的支持,  

最近查阅了一些wmi的资料整理如下:

--wmi事件的例子:
http://msdn2.microsoft.com/en-us/library/aa393013(vs.85).aspx

--delphi的wmi控件:
http://www.online-admin.com/wmiset.html

--how   to   detect   network   connect/disconnect?
http://www.online-admin.com/howtozone/network_detect_connect.html
不知道为什么,这个事不能触发!

现在的解决方法是用wmi定时查询网络适配器的信息,   并检查状态字段的值:

wmi   namespace:root\cimv2
wql:   select       *       from     win32_networkadapter

查询结果中有一字段名为:netconnectionstatus,   值为0时表示断开连接,   值为1时表示已连接。

发表于:2008-01-22 17:10:159楼 得分:0
纠正错误:
值为2时表示已连接。
发表于:2008-01-22 18:54:5410楼 得分:0
mark
发表于:2008-01-22 19:36:0111楼 得分:0
喔,强贴,学习、留名!


快速检索

最新资讯
热门点击