Recent

Author Topic: (Windows only) Network interfaces  (Read 2909 times)

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
(Windows only) Network interfaces
« on: January 09, 2022, 10:33:55 pm »
Hi @ all,

as promised in another topic, here is my unit for reading and setting the network interfaces (IP, Subnetmask etc.). It is a collection of my work and of the knowledge of other people posted all over the internet (Stack Overflow etc.). I am sorry that I didn't take notice where I got what from, so the authors of some pieces of the code will unfortunately remain uncredited.

Usage

Find the network interfaces and feed the names to a Combobox (cbAdapters):
Code: Pascal  [Select][+][-]
  1. GetLocalAdaptersWMI;
  2.     if SizeOf(Interfaces) > 0 then
  3.     begin
  4.       for i := Low(Interfaces) to High(Interfaces) do
  5.         cbAdapters.Items.Add(Interfaces[i].Description);
  6.     end;  

Check if there is a connection (LAN cable connected, Wi-Fi connected). If not (IP-Adress is empty) - read the last info as saved to registry:
Code: Pascal  [Select][+][-]
  1. IsAdapterConnectedWMI(cbAdapters.Items[cbAdapters.ItemIndex],
  2.       cbAdapters.ItemIndex);
  3.     if trim(Interfaces[cbAdapters.ItemIndex].IP_Address) = '' then
  4.       GetLocalAdapterInfoREG(cbAdapters.Items[cbAdapters.ItemIndex],
  5.         cbAdapters.ItemIndex);
If an adapter is not connected at the moment, you can't get the IP settings through WMI interface, but you can read it from the registry (corresponding function is untRegistry). You should now have the last IP-Address in interfaces[].IP_Address

Use the info we got from Interfaces (cbAdapters is our ComboBox filled with adapter names, lbInfo are Labels and cbInfo9 is a CheckBox):
Code: Pascal  [Select][+][-]
  1. var
  2.   i: integer;
  3. begin
  4.   i := cbAdapters.ItemIndex;
  5.   lbInfo5.Caption := Interfaces[i].MAC;
  6.   lbInfo6.Caption := Interfaces[i].IP_Address;
  7.   lbInfo7.Caption := Interfaces[i].Subnet_Mask;
  8.   lbInfo8.Caption := Interfaces[i].Gateway_Address;
  9.   if Interfaces[i].DHCP_Enabled = 1 then
  10.     cbInfo9.Checked := True
  11.   else
  12.     cbInfo9.Checked := False;
  13.  
  14.   if Logging then
  15.   begin
  16.     Log(GetNDISAdapterTypeString(Interfaces[i].PhysicalMediumType));
  17.     Log(GetNetConnectionStatusString(Interfaces[i].ConnectionStatus));
  18.   end;
  19. end;

Send your settings to an adapter:
Code: Pascal  [Select][+][-]
  1. var
  2.   i: integer;
  3.   IP, Subnet, Gateway: WideString;
  4.   test: TIPv4Rec;
  5. begin
  6.   try
  7.     CoInitialize(nil);
  8.     try
  9.       if cbDHCP.Checked then //CheckBox for selecting DHCP or static address
  10.       begin
  11.         SetDynamicIpAddress(cbAdapters.Text); //all the functions are using network interface name (description) for the access
  12.         if LastError <> '' then
  13.           Log(LastError);
  14.         ReleaseDHCP(cbAdapters.Text);
  15.         if LastError <> '' then
  16.           Log(LastError);
  17.         RenewDHCP(cbAdapters.Text);
  18.         if LastError <> '' then
  19.           Log(LastError);
  20.       end
  21.       else
  22.       begin
  23.         IP := TrimSpace(meIPAddr.Text); //MaskedEdits containing our settings
  24.         Subnet := TrimSpace(meSubnet.Text);
  25.         Gateway := TrimSpace(meGateway.Text);
  26.         if (Gateway = '0.0.0.0') or not StrToIPV4(Gateway, test) then
  27.           Gateway := '';
  28.         SetStaticIpAddress(cbAdapters.Text, IP, Subnet, Gateway);
  29.         if LastError <> '' then
  30.           Log(LastError);
  31.       end;
  32.     finally
  33.       CoUninitialize;
  34.     end;
  35.   except
  36.     on E: EOleException do
  37.       Log(Format('EOleException %s %x', [E.Message, E.ErrorCode]));
  38.     on E: Exception do
  39.       Log(E.ClassName + ':' + E.Message);
  40.   end;
  41. end;

I know it isn't so easy to read and use my code because it is ripped from a GUI program, but I hope someone can make a use of it.

If anyone makes a use of it, please leave a note here to feed my ego :)
« Last Edit: January 09, 2022, 10:41:20 pm by bobby100 »

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1430
    • Lebeau Software
Re: (Windows only) Network interfaces
« Reply #1 on: January 10, 2022, 02:10:28 am »
Find the network interfaces and feed the names to a Combobox (cbAdapters):
Code: Pascal  [Select][+][-]
  1. GetLocalAdaptersWMI;

I wonder why you are using WMI for this, instead of using more native system APIs, like GetAdapters(Info|Addresses)?
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

bobby100

  • Sr. Member
  • ****
  • Posts: 260
    • Malzilla
Re: (Windows only) Network interfaces
« Reply #2 on: January 10, 2022, 06:04:15 am »
Hi Remy,

it is easy for you to say (I know that you have the knowledge), but try to get any info if you are beginning from zero. Google for "change ip address programmatically" or similar, and all you will get is about C#, powershell, WMI...
I did found some examples built around native API, but not all I need. For some functions, I needed to use WMI because of the available info. At the end, I've decided to do all over the WMI, and not with a combination of native/WMI.
There was also some info on the net, which APIs will be deprecated in the future versions of Windows, and MS' advice was to use WMI because they will keep the frontend API as is for some time, thus giving me hope that my app will keep working with future versions of Windows for at least some time.
I can't recall all the details, but I can recall that I’ve made some decisions according to such kind of info.

 

TinyPortal © 2005-2018