Search code examples
delphidelphi-7

Problems in setting DNS address


I'm using one popular Delphi function and one laptop with Wi-fi adapter connected on attempt to set preferred and alternative dns server address and catch an error saying - "Invalid Syntax". I think "Win32_NetworkAdapterConfiguration" function work only in Ethernet adapters and not in Wi-fi adapters, or I'm wrong?

Exceptions generated:

http://prntscr.com/4qvjmz enter image description here http://prntscr.com/4qvjvn
enter image description here

And this is the function:

uses
ComObj, ActiveX, UrlMon, Variants;

    function SetDnsServers(const APrimaryDNS : string;
                           const AAlternateDNS : string = '') : integer;
    var Retvar : integer;
        oBindObj : IDispatch;
        oNetAdapters,oNetAdapter,
        oDnsAddr,oWMIService : OleVariant;
        i,iValue,iSize : longword;
        oEnum : IEnumvariant;
        oCtx : IBindCtx;
        oMk : IMoniker;
        sFileObj : widestring;
    begin
      Retvar := 0;
      sFileObj := 'winmgmts:\\.\root\cimv2';
      iSize := 0;
      if APrimaryDNS <> '' then inc(iSize);
      if AAlternateDNS <> '' then inc(iSize);

      if iSize = 0 then begin
       oDnsAddr := VarArrayCreate([1,iSize],varOleStr);
       oDnsAddr[1] := APrimaryDNS;
       if iSize > 1 then oDnsAddr[2] := AAlternateDNS;
      end;

      OleCheck(CreateBindCtx(0,oCtx));
      OleCheck(MkParseDisplayNameEx(oCtx,PWideChar(sFileObj),i,oMk));
      OleCheck(oMk.BindToObject(oCtx,nil,IUnknown,oBindObj));
      oWMIService := oBindObj;

      oNetAdapters := oWMIService.ExecQuery('Select * from ' +
                                            'Win32_NetworkAdapterConfiguration ' +
                                            'where IPEnabled=TRUE');
      oEnum := IUnknown(oNetAdapters._NewEnum) as IEnumVariant;

      while oEnum.Next(1,oNetAdapter,iValue) = 0 do begin
        try
          if iSize > 0 then
            Retvar := oNetAdapter.SetDNSServerSearchOrder(oDnsAddr)
          else
            Retvar := oNetAdapter.SetDNSServerSearchOrder();
        except
          Retvar := -1;
        end;

        oNetAdapter := Unassigned;
      end;

      oDnsAddr := Unassigned;
      oNetAdapters := Unassigned;
      oWMIService := Unassigned;
      Result := Retvar;
    end;



//Usage:

    begin
    SetDnsServers('104.131.220.61','104.131.220.61');

    end.

Solution

  • I solved my problem with other function, thank you all!

    function ArrayToVarArray(Arr : Array Of string):OleVariant; overload;
    var
     i : integer;
    begin
        Result   :=VarArrayCreate([0, High(Arr)], varVariant);
        for i:=Low(Arr) to High(Arr) do
         Result[i]:=Arr[i];
    end;
    
    procedure  SetDNS();
    const
      wbemFlagForwardOnly = $00000020;
    var
      FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;
      FWbemObjectSet: OLEVariant;
      FWbemObject   : OLEVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
      vIPAddress         : OleVariant;
    begin
    CoInitialize(nil);
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
      FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapterConfiguration Where IPEnabled=True','WQL',wbemFlagForwardOnly);
      oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      while oEnum.Next(1, FWbemObject, iValue) = 0 do
      begin
        vIPAddress   := ArrayToVarArray(['104.131.220.61']);
        if FWbemObject.SetDNSServerSearchOrder(vIPAddress) = 0 then
        begin
        exit;
        end;
        VarClear(vIPAddress);
        FWbemObject:=Unassigned;
        CoUninitialize;
      end;
    end;