Reinventing the wheel
March 28, 2024, 11:18:56 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News:
 
   Home   Help Members Tags Login Register  
Del.icio.us Digg FURL FaceBook Stumble Upon Reddit SlashDot Ask Google Bookmarks MSN Live Spurl Technorati Yahoo My Web

Pages: [1]
  Print  
Author Topic: 'Enable/disable network adapters' code example  (Read 30009 times)
bushtor
Good users
*
Posts: 2


View Profile
« on: May 15, 2009, 10:20:15 AM »

Hi,

Thanks for the 'enable/disable network adapters' code example :-)

I have a couple of questions:

Does it require administrator's priviledges on the computer it is running? (I only need to monitor the local computer).   I just need to retrieve the adapters status if activated or deactivated....

Secondly, can the code be slightly modified to enumerate dialup connections too...?

Thanks again for a nice piece of code

regards tor
Logged
Reinventing the wheel
« on: May 15, 2009, 10:20:15 AM »

 Logged
ciuly
Administrator
Good users
*****
Posts: 235



View Profile WWW
« Reply #1 on: May 15, 2009, 11:56:19 AM »

can you post a link to that? AFAIK, I never released such a code, only to show the status of the adapter.
Logged
rionroc
Good users
*
Posts: 26


View Profile
« Reply #2 on: May 15, 2009, 12:15:50 PM »

Here is some code that should help get you started along. It is able to detect network changes, enumerate the adapter/interface pairs, and also allows you to disable/re-enable any specific interface. I am posting the sample app code first, then the component code. The component code requires the ip helper conversion units from jedi (the link is displayed in the component.).

If you have questions, please do not ask me,  ask Sir Ciuly, because he knows better than me.


Sample app code (form with 2 buttons and 1 memo on it)

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    NetAdapter1: TNetAdapter;
    Memo1: TMemo;
    Button2: TButton;
    procedure NetAdapter1Connect(Sender: TObject; IntfAdapter: _MIB_IFROW);
    procedure NetAdapter1Disconnect(Sender: TObject; IntfAdapter: _MIB_IFROW);
    procedure NetAdapter1StateChange(Sender: TObject; IntfAdapter: _MIB_IFROW; LastState, LastAdminState: Cardinal);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

procedure UpdateInfo(Memo: TMemo; Row: _MIB_IFROW);
begin
  with Memo do
  begin
     Lines.Add(Format('  Name: %s', [InterfaceName(Row)]));
     Lines.Add(Format('  Operational State: %d', [Row.dwOperStatus]));
     Lines.Add(Format('  Admin State: %d', [Row.dwAdminStatus]));
  end;
end;

procedure TForm1.NetAdapter1Connect(Sender: TObject; IntfAdapter: _MIB_IFROW);
begin
  Memo1.Lines.Add(Format('%s connected', [InterfaceName(IntfAdapter)]));
  UpdateInfo(Memo1, IntfAdapter);
end;

procedure TForm1.NetAdapter1Disconnect(Sender: TObject; IntfAdapter: _MIB_IFROW);
begin
  Memo1.Lines.Add(Format('%s disconnected', [InterfaceName(IntfAdapter)]));
  UpdateInfo(Memo1, IntfAdapter);
end;

procedure TForm1.NetAdapter1StateChange(Sender: TObject; IntfAdapter: _MIB_IFROW; LastState, LastAdminState: Cardinal);
begin
  Memo1.Lines.Add(Format('%s state change', [InterfaceName(IntfAdapter)]));
  UpdateInfo(Memo1, IntfAdapter);
  if InterfaceIsConnected(IntfAdapter) then
     Memo1.Lines.Add('-- Connected -- ')
  else
     Memo1.Lines.Add('-- Disconnected -- ');
end;

procedure TForm1.Button1Click(Sender: TObject);
var  dwIndex:       Integer;
begin
  for dwIndex:=0 to Pred(NetAdapter1.IntfAdapterCount) do
     NetAdapter1.DisableIntfAdapter(NetAdapter1[dwIndex]);
end;

procedure TForm1.Button2Click(Sender: TObject);
var  dwIndex:       Integer;
begin
  for dwIndex:=0 to Pred(NetAdapter1.IntfAdapterCount) do
     NetAdapter1.EnableIntfAdapter(NetAdapter1[dwIndex]);
end;


------------------- Component Code --------------------

unit NetState;
// http://ftp://delphi-jedi.org/api/IPHlpAPI.zip
interface

////////////////////////////////////////////////////////////////////////////////
//   Include Units (IP Helper units: http://ftp://delphi-jedi.org/api/IPHlpAPI.zip)
////////////////////////////////////////////////////////////////////////////////
uses
  Windows,
  SysUtils,
  Messages,
  Classes,
  Graphics,
  Controls,
  ExtCtrls,
  Forms,
  Dialogs,
  WinSock,
  WinInet,
  IpExport,
  IpHlpApi,
  IpTypes,
  IpIfConst,
  IpRtrMib;

////////////////////////////////////////////////////////////////////////////////
//   Network adapter constants
////////////////////////////////////////////////////////////////////////////////
const
  SPEED_MODEM          =  9600;

////////////////////////////////////////////////////////////////////////////////
//   Network adapter component
////////////////////////////////////////////////////////////////////////////////
type
  // Event handler type declarations
  TOnConnect           =  procedure(Sender: TObject; IntfAdapter: TMibIfRow) of object;
  TOnDisconnect        =  procedure(Sender: TObject; IntfAdapter: TMibIfRow) of object;
  TOnStateChange       =  procedure(Sender: TObject; IntfAdapter: TMibIfRow; LastState, LastAdminState: DWORD) of object;
  // Component declaration
  TNetAdapter          =  class(TComponent)
  private
     // Private declarations
     FTimer:           TTimer;
     FTable:           PMibIfTable;
     FOnConnect:       TOnConnect;
     FOnDisconnect:    TOnDisconnect;
     FOnStateChange:   TOnStateChange;
  protected
     // Protected declarations
     function          GetInterval: Integer;
     function          GetWatch: Boolean;
     function          GetIntfAdapters(Index: Integer): TMibIfRow;
     function          GetIntfAdapterCount: Integer;
     procedure         GetIntfAdapterTable;
     procedure         OnWatchFired(Sender: TObject);
     procedure         SetInterval(Value: Integer);
     procedure         SetWatch(Value: Boolean);
  public
     // Public declarations
     constructor       Create(AOwner: TComponent); override;
     destructor        Destroy; override;
     procedure         DisableIntfAdapter(Row: TMibIfRow);
     procedure         EnableIntfAdapter(Row: TMibIfRow);
     property          IntfAdapterCount: Integer read GetIntfAdapterCount;
     property          IntfAdapters[Index: Integer]: TMibIfRow read GetIntfAdapters; default;
  published
     // Published declarations
     property          OnConnect: TOnConnect read FOnConnect write FOnConnect;
     property          OnDisconnect: TOnDisconnect read FOnDisconnect write FOnDisconnect;
     property          OnStateChange: TOnStateChange read FOnStateChange write FOnStateChange;
     property          WatchChanges: Boolean read GetWatch write SetWatch;
     property          WatchInterval: Integer read GetInterval write SetInterval;
  end;

////////////////////////////////////////////////////////////////////////////////
//   Utility functions for handling of the interface row information
////////////////////////////////////////////////////////////////////////////////
function   InterfaceName(IntfAdapter: TMibIfRow): PChar;
function   InterfaceIsConnected(IntfAdapter: TMibIfRow): Boolean;
function   InterfaceIsModem(IntfAdapter: TMibIfRow): Boolean;

procedure Register;

implementation

function InterfaceName(IntfAdapter: TMibIfRow): PChar;
begin
  result:=PChar(@IntfAdapter.bDescr);
end;

function InterfaceIsConnected(IntfAdapter: TMibIfRow): Boolean;
begin
  result:=(IntfAdapter.dwAdminStatus = MIB_IF_ADMIN_STATUS_UP) and (IntfAdapter.dwOperStatus >= MIB_IF_OPER_STATUS_CONNECTED);
end;

function InterfaceIsModem(IntfAdapter: TMibIfRow): Boolean;
begin
  result:=((IntfAdapter.dwType = MIB_IF_TYPE_ETHERNET) and (IntfAdapter.dwSpeed = SPEED_MODEM)) or (IntfAdapter.dwType = MIB_IF_TYPE_PPP);
end;

// TNetAdapter
procedure TNetAdapter.DisableIntfAdapter(Row: TMibIfRow);
begin

  // Set admin status for row and call SetIfEntry
  Row.dwAdminStatus:=MIB_IF_ADMIN_STATUS_DOWN;

  // Set entry
  SetIfEntry(Row);

end;

procedure TNetAdapter.EnableIntfAdapter(Row: TMibIfRow);
begin

  // Set admin status for row and call SetIfEntry
  Row.dwAdminStatus:=MIB_IF_ADMIN_STATUS_UP;

  // Set entry
  SetIfEntry(Row);

end;

function TNetAdapter.GetInterval: Integer;
begin

  // Return the interval for the timer control
  result:=FTimer.Interval;

end;

function TNetAdapter.GetWatch: Boolean;
begin

  // Return the timer control enabled state
  result:=FTimer.Enabled;

end;

procedure TNetAdapter.SetInterval(Value: Integer);
begin

  // Update the timer control interval
  FTimer.Interval:=Value;

end;

procedure TNetAdapter.SetWatch(Value: Boolean);
begin

  // Update the timer control enabled state
  FTimer.Enabled:=Value;

end;

function TNetAdapter.GetIntfAdapters(Index: Integer): TMibIfRow;
begin

  // Check the table to make sure the request is in range
  if (FTable = nil) or (Index < 0) or (DWORD(Index) >= FTable^.dwNumEntries) then raise Exception.Create('Invalid Index');

  // Return the row
  result:=FTable^.Table[Index];

end;

function TNetAdapter.GetIntfAdapterCount: Integer;
begin

  // Check table
  if Assigned(FTable) then
     // Return the current count of interface/adapters
     result:=FTable^.dwNumEntries
  else
     // No table
     result:=0;

end;

procedure TNetAdapter.GetIntfAdapterTable;
var  lpIntfTable:   PMibIfTable;
     lpSwap:        Pointer;
     dwIndex:       ULONG;
     dwOldIndex:    ULONG;
     dwSize:        ULONG;
     bChanged:      Boolean;
     bExists:       Boolean;
begin

  // Set the default table
  lpIntfTable:=nil;

  // Make the call to get the required size
  try
     // Set the default size to allocate
     dwSize:=0;
     // Make the call to get the table size
     if (GetIfTable(nil, dwSize, True) = ERROR_INSUFFICIENT_BUFFER) then
     begin
        // Allocate memory for the table
        lpIntfTable:=AllocMem(dwSize);
        // Make the call again
        if (GetIfTable(lpIntfTable, dwSize, True) = NO_ERROR) then
        begin
           // We now have the table. If the old table is nil, then this is the
           // first call and there is nothing to compare to, so just assign the
           // table over.
           if (FTable = nil) then
           begin
              // Assign and clear var so the memory is not freed
              FTable:=lpIntfTable;
              lpIntfTable:=nil;
           end
           else
           begin
              // Swap table pointers
              lpSwap:=FTable;
              FTable:=lpIntfTable;
              lpIntfTable:=lpSwap;
              // Check for connects first and changes first
              for dwIndex:=0 to Pred(FTable^.dwNumEntries) do
              begin
                 // Check to see if this is a new entry
                 bExists:=False;
                 bChanged:=False;
                 dwOldIndex:=0;
                 while (dwOldIndex < lpIntfTable^.dwNumEntries) do
                 begin
                    // Check index
                    if (FTable^.table[dwIndex].dwIndex = lpIntfTable^.table[dwOldIndex].dwIndex) then
                    begin
                       // Entry exists
                       bExists:=True;
                       // Has it changed?
                       bChanged:=not((FTable^.table[dwIndex].dwAdminStatus = lpIntfTable^.table[dwOldIndex].dwAdminStatus) and
                                 (FTable^.table[dwIndex].dwOperStatus = lpIntfTable^.table[dwOldIndex].dwOperStatus));
                       // Done either way
                       break;
                    end;
                    // Next index
                    Inc(dwOldIndex);
                 end;
                 // Does the entry exist? If not, then we will need to fire a connect change
                 if bExists then
                 begin
                    // Check for change
                    if bChanged and Assigned(FOnStateChange) then
                       FOnStateChange(Self, FTable^.table[dwIndex], lpIntfTable^.table[dwOldIndex].dwOperStatus, lpIntfTable^.table[dwOldIndex].dwAdminStatus);
                 end
                 else if Assigned(FOnConnect) then
                    // Fire the OnConnect event
                    FOnConnect(Self, FTable^.table[dwIndex]);
              end;
              // Now we need to check for disconnects (those in old table but not in new)
              for dwOldIndex:=0 to Pred(lpIntfTable^.dwNumEntries) do
              begin
                 // Check to see if this entry still exists
                 bExists:=False;
                 dwIndex:=0;
                 while (dwIndex < FTable^.dwNumEntries) do
                 begin
                    // Check index
                    if (FTable^.table[dwIndex].dwIndex = lpIntfTable^.table[dwOldIndex].dwIndex) then
                    begin
                       // Entry exists
                       bExists:=True;
                       // Done either way
                       break;
                    end;
                    // Next index
                    Inc(dwIndex);
                 end;
                 // Does the entry exist? If not, then we will need to fire a disconnect event
                 if not(bExists) and Assigned(FOnDisconnect) then FOnDisconnect(Self, lpIntfTable^.table[dwOldIndex]);
              end;
           end;
        end;
     end;
  finally
     // Free the table memory
     if Assigned(lpIntfTable) then FreeMem(lpIntfTable);
  end;

end;

procedure TNetAdapter.OnWatchFired(Sender: TObject);
begin

  // Resource protection
  try
     // Disable the timer
     FTimer.Enabled:=False;
     // Update the network interface table
     GetIntfAdapterTable;
  finally
     // Re-enable the timer
     FTimer.Enabled:=True;
  end;

end;

constructor TNetAdapter.Create(AOwner: TComponent);
begin

  // Perform inherited
  inherited Create(AOwner);

  // Starting defaults
  FTimer:=TTimer.Create(Self);
  FTimer.Interval:=1000;
  FTimer.Enabled:=False;
  FTimer.OnTimer:=OnWatchFired;
  FTable:=nil;

  // Load the initial table
  GetIntfAdapterTable;

end;

destructor TNetAdapter.Destroy;
begin

  // Stop and free the timer
  FTimer.Enabled:=False;
  FTimer.Free;

  // Free memory allocated for the table
  if Assigned(FTable) then FreeMem(FTable);

  // Perform inherited
  inherited Destroy;

end;

procedure Register;
begin

  // Register the component with the IDE
  RegisterComponents('Additional', [TNetAdapter]);

end;

end.


Got it from other sites. (^_^)
And a sample code in zip format that may help you analyze:
http://www.yeahware.com/download/enable.zip


rionroc
Delphi zombie, because delphi is always alive.
Logged

(^_^)
bushtor
Good users
*
Posts: 2


View Profile
« Reply #3 on: May 15, 2009, 01:33:02 PM »

Thanks rionroc, will look at the code.

Ciuly,
Sorry about the subject name.  I mean:

http://www.ciuly.com/delphi/wmi/networkAdapterStatus/index.html

The example form's caption name use 'Enable/disable ...' so that's where I saw it.

Anyhow, I'm trying to put together an application to be run on students' computers during tests and exams.  In many subjeccts they are allowed to use their own computers with any resource saved to their disks, however they are not allowed to communicate by any means.

Hence I wanted to display a small always-stay-on-top window on their screen listing all their network adapters and dialup connections colored according to their activated state.  Then it's easy for the exam staff to visually verify that all network adapters are deactivated.  

Obviously wireless network, bluetooth and dialup (3G mobile cards) are most interesting.  Loopback, 1394 and  wired adapters could mostly be ignored in this situation due to their nature.

Since I've come to the gurus :-) I'd like to ask some questions, and I'd be happy to receive comments.

With the code from the link above I assume that it might be possible to modify it with other parameters to also get a list of dialup connections.  Is this true or will dialup enumeration require a totally different approach?

Would it be possible to limit the query seeking for specific types of adapters, like wireless and bluetooth one and ignore loopback adapters and 1394 oners by changing parameters in the code above..?

Would it also be possible to check if a network cable is plugged in or not with this code...?

Sorry for bugging you, but thanks for any comments on the above topics :-)

best regards

Tor
Logged
rionroc
Good users
*
Posts: 26


View Profile
« Reply #4 on: May 15, 2009, 10:46:51 PM »

I understand that this is the one you are basing.
http://www.yeahware.com/download/enable.zip

>>With the code from the link above I assume that it might be possible to modify it with other parameters to also get a list of dialup connections. Is this true or will dialup enumeration require a totally different approach?
for me, NO!, you could select and disable the device of dialup, such as the modem device. (but you must know first the name of the modem device)


>>Would it be possible to limit the query seeking for specific types of adapters, like wireless and bluetooth one and ignore loopback adapters and 1394 oners by changing parameters in the code above..?   YES


>>Would it also be possible to check if a network cable is plugged in or not with this code...?   is NOT with that code or link.
Logged

(^_^)
rionroc
Good users
*
Posts: 26


View Profile
« Reply #5 on: May 16, 2009, 05:35:53 AM »

Ops!

Sorry for my answer, I thought your asking for any of as.


Anyway! Good luck!

Cheers!
Logged

(^_^)
Reinventing the wheel
   

 Logged
Tags:
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC | Sitemap Valid XHTML 1.0! Valid CSS!
Page created in 0.046 seconds with 27 queries.