Title: 'Enable/disable network adapters' code example Post by: bushtor 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 Title: 'Enable/disable network adapters' code example Post by: ciuly 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.
Title: 'Enable/disable network adapters' code example Post by: rionroc 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; // ftp://delphi-jedi.org/api/IPHlpAPI.zip interface //////////////////////////////////////////////////////////////////////////////// // Include Units (IP Helper units: 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. Title: 'Enable/disable network adapters' code example Post by: bushtor 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 Title: 'Enable/disable network adapters' code example Post by: rionroc 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. Title: 'Enable/disable network adapters' code example Post by: rionroc 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! |