user3878654
user3878654

Reputation:

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.

Upvotes: 1

Views: 1243

Answers (2)

user3878654
user3878654

Reputation:

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;

Upvotes: 3

TheStatehz
TheStatehz

Reputation: 310

oDnsAddr is unassigned because iSize is being incremented but your condition means it will never be populated.

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

Then your later condition is being met

if iSize > 0 then
    Retvar := oNetAdapter.SetDNSServerSearchOrder(oDnsAddr)

Providing an unassigned OleVariant.

It should be:

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;

Upvotes: 2

Related Questions