(*

type
  float = extended;

function IEEE4tofloat(const up:TByteBuffer):float;
var
  mantisa:longint;
  exponent:integer;
  f:float;
begin
  mantisa := up[0] or ( longint(up[1]) shl 8 ) or
   (longint(up[2]) shl 16) or $800000;
  if (up[3]and $80) <> 0 then
    mantisa := -mantisa;
  exponent := (up[2] shr 7) or (( integer(up[3]) and $7f) shl 1);
  f := float(ldexp( mantisa, exponent - $7f - 23));
  Result := f;
end;


function UL_fd_wait(UL_fd: HANDLE; wait_sec: longint):longint;
var
  ret:longint;
  bytes_ret: DWORD;
  loops:longint;
  {struct timeval timeout;
  fd_set set;}
begin
  loops := 0;
  repeat
     if(not DeviceIoControl(UL_fd, UL_INEPOLL, nil,0, @ret,
      sizeof(ret), bytes_ret,nil)) then
     begin
       Result := -1;
       exit;
     end;
     if(ret <> 0) then begin
       Result := ret;
       exit;
     end;
     Sleep(100);
     inc(loops);
  until loops >= wait_sec*10;
  Result := 0;
end;

function send_query(UL_fd:HANDLE ; dadr, cmd, flg: longint;
  buf:pointer; len:longint): longint;
var
  ret: longint;
  bytes_ret, b_ret: DWORD;
  msginfo: TULMessage;
  wres:boolean;
begin
  FillChar(msginfo, sizeof(msginfo), 0);
  msginfo.dadr := dadr;
  msginfo.cmd := cmd;
  msginfo.flg := UL_BFL_M2IN or flg; {windows}
  if not DeviceIoControl(UL_fd, UL_NEWMSG, @msginfo, sizeof(TULMessage),
    nil, 0, bytes_ret, nil) then
  begin
    Result := -1;
    exit;
  end;{windows}
{  WriteFile(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD;
  var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; }
  if buf = nil then
    wres := WriteFile(UL_fd, buf, 0, b_ret, nil)
  else
    wres := WriteFile(UL_fd, buf^, len, b_ret, nil);
  if (len > 0) and ((not wres) or (longint(b_ret) <> len))
  then begin
    DeviceIoControl(UL_fd,UL_ABORTMSG,nil,0,nil,0, b_ret, nil);
    Result := -1;
    exit;
  end;
  ret := b_ret;
  FillChar(msginfo,sizeof(msginfo),0);
  msginfo.flg := UL_BFL_REC or UL_BFL_M2IN;

  if (not DeviceIoControl(UL_fd, UL_TAILMSG, @msginfo,
    sizeof(TULMessage), nil, 0, bytes_ret, nil)) then
  begin
    DeviceIoControl(UL_fd, UL_ABORTMSG, nil, 0, nil, 0, bytes_ret, nil);
    Result := -1;
    exit;
  end;
  if(not DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
    bytes_ret, nil)) then
  begin
    Result := -1;
    exit;
  end;
  Result := ret;
end;

function send_query_wait(UL_fd: HANDLE ; dadr, cmd, flg: longint;
  bufin:pointer; lenin:longint; var bufout:pointer; var lenout: longint):longint;
var
  stamp: longint;
  ret: longint;
  len: longint;
  bytes_ret, b_ret: DWORD;
  msginfo: TULMessage;
begin
  stamp := send_query(UL_fd, dadr, cmd, flg, bufin, lenin);
  if (stamp < 0) then begin
    Result := stamp;
    exit;
  end;

  while true do begin

    ret := UL_fd_wait(UL_fd, 10);
    if (ret<=0) then begin
      if ret <> 0 then
        Result :=  ret
      else
        Result := -1;
      exit;
    end;

    if (not DeviceIoControl(UL_fd,UL_ACCEPTMSG,
      nil, 0, @msginfo, sizeof(TULMessage), bytes_ret, nil)) then
    begin
      Result := -1;
      exit;
    end;

    if (msginfo.stamp = stamp) then
    begin
      if(msginfo.flg and UL_BFL_FAIL) <> 0 then
      begin
        DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
          bytes_ret, nil);
        Result := -2;
        exit;
      end;
      if(not DeviceIoControl(UL_fd, UL_ACTAILMSG, nil,
        0, @msginfo, sizeof(TULMessage), bytes_ret, nil)) then
      begin
        DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
          bytes_ret, nil);
        Result := -2;
        exit;
      end;
      if msginfo.len > 0{(bufout <> nil) and  (lenout <> 0)} then begin
        len := msginfo.len;
        if bufout = nil then begin
          GetMem(bufout, len)
        end else begin
          if lenout < len then
            len := lenout;
        end;
        if(not ReadFile(UL_fd, bufout^, len, b_ret, nil)) or (longint(b_ret) <> len) then
        begin
          ret := b_ret;
          DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
            bytes_ret, nil);
          Result := -3;
          exit;
	end;
        ret := b_ret;
        lenout := len;
      end;
      DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret,
        sizeof(ret), bytes_ret, nil);
      Result := msginfo.len;
      exit;
    end;
    DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
      bytes_ret, nil);
  end;
end;

function send_command(UL_fd:HANDLE; dadr:longint; cmd:longint; flg:longint;
  buf:PByteBuffer; len:longint):longint;
var
  ret:longint;
  msginfo:TULMessage;
  bytes_ret:DWORD;
  b_ret:DWORD;
  wres:boolean;
begin
  FillChar(msginfo, sizeof(msginfo), 0);
  msginfo.dadr :=dadr;
  msginfo.cmd:=cmd;
  msginfo.flg:=UL_BFL_M2IN or flg;
  if(not DeviceIoControl(UL_fd, UL_NEWMSG, @msginfo, sizeof(TULMessage),
    nil, 0, bytes_ret, nil)) then begin
    Result :=-1;
    SysLogLog(leError, 'SendCommand DeviceIOControl failed.');
    exit;
  end;

  if(len <> 0) then begin
    if buf = nil then
      wres := WriteFile(UL_fd, buf, 0, b_ret, nil)
    else
      wres := WriteFile(UL_fd, buf^, len, b_ret, nil);
    if((not wres) or (longint(b_ret) <> len))then
    begin
      DeviceIoControl(UL_fd,UL_ABORTMSG,nil,0,nil,0, bytes_ret,nil);
      Result := -1;
      exit;
    end else
      ret := b_ret;
  end;
  if (not DeviceIoControl(UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
    bytes_ret,nil)) then
  begin
    Result := -1;
    exit;
  end;
  Result := ret;
end;

function send_command_wait(UL_fd:HANDLE; dadr:longint; cmd:longint; flg:longint;
 buf:PByteBuffer; len:longint):longint;
var
  stamp:longint;
  bytes_ret:DWORD;
  ret:longint;
  msginfo:TULMessage;
begin
  stamp := send_command(UL_fd,dadr,cmd,flg,buf,len);
  if (stamp < 0) then begin
    Result := stamp;
    exit;
  end;
  while true do begin
    ret := UL_fd_wait(UL_fd, 10);
    if (ret <= 0) then begin
      if ret < 0 then
        Result := ret
      else
        Result := -1;
      exit;
    end;
    if(not DeviceIoControl(UL_fd,UL_ACCEPTMSG, nil, 0, @msginfo, sizeof(TULMessage),
      bytes_ret,nil)) then begin
      Result := -1;
      exit;
    end;
    DeviceIoControl(UL_fd, UL_FREEMSG, nil,0, @ret,sizeof(ret), bytes_ret,nil);
    if(msginfo.stamp = stamp) then begin
      if(msginfo.flg and UL_BFL_FAIL) <> 0 then begin
        Result := -2;
        exit;
      end else begin
        Result := 1;
        exit;
      end;
    end;
  end;
end;

function UL_GetModULeList(max_addr:longint; sl:TStringList):longint;
var
  ret, i: longint;
  UL_fd: HANDLE;
  buf: PCharBuffer;
  buf_len: longint;
  count:longint;
  s,sn:shortstring;
label ex;
begin
  buf := nil;
  buf_len := 0;
  count := 0;
  try
    InfoFormShow('Detecting modULes');
    UL_fd := CreateFile(UL_DEV_NAME, GENERIC_READ or GENERIC_WRITE,
      0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if (UL_fd = INVALID_HANDLE_VALUE) then begin
      ShowMessage('ULan open failed');
      count := -1;{= Result}
      goto ex;
    end;
    for i := 1 to max_addr do begin

      ret := send_query_wait(UL_fd, i, UL_CMD_SID,
                          UL_BFL_NORE or UL_BFL_PRQ, nil, 0,
                          pointer(buf), buf_len);
      if( ret >= 0 ) then begin
        inc(count);
        ret := 0;
        s := '';
        while (ret < buf_len) and (buf^[ret] <> #0) do begin
          s := s + buf^[ret];
          inc(ret);
        end;
        str(i:2, sn);
        sl.Add(sn + ' ' + s);
      end;
      if (buf <> nil) then
        FreeMem(buf);
      buf := nil;
    end;

    CloseHandle(UL_fd);
ex:
  finally
    Result := count;
    InfoFormHide;
  end;
end;

function ULoi_open(UL_dev_name: PChar; adr: longint; cmd: longint;
  bcmd: longint; timeout: longint): PULoi_coninfo;
var
  coninfo: PULoi_coninfo;
  msginfo: TULMessage ;
  UL_fd: HANDLE ;
  bytes_ret: DWORD;
begin
  if timeout = 0 then
    timeout:=10;
  if bcmd = 0 then
    bcmd :=$11;
  UL_fd := CreateFile(UL_dev_name, GENERIC_READ or GENERIC_WRITE,
                   0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if (UL_fd = INVALID_HANDLE_VALUE) then begin
    Result := nil;
    exit;
  end;

  GetMem(coninfo, sizeof(ULoi_coninfo));
  if (coninfo <> nil) then begin
    FillChar(coninfo^, sizeof(coninfo^), 0);
    FillChar(msginfo, sizeof(TULMessage), 0);
    msginfo.sadr:= adr;
    msginfo.cmd := bcmd;
    if(DeviceIoControl(UL_fd, UL_ADDFILT, @msginfo, sizeof(TULMessage),
					   nil,0, bytes_ret, nil))
    then begin
     coninfo^.UL_fd := UL_fd;
     coninfo^.adr := adr;
     coninfo^.cmd := cmd;
     coninfo^.bcmd := bcmd;
     coninfo^.timeout :=timeout;
     Result := coninfo;
     exit;
    end;
    FreeMem(coninfo);
  end;
  CloseHandle(UL_fd);
  Result := nil;
end;

function ULoi_transfer(coninfo:PULoi_coninfo; bufin:PByteBuffer;
  lenin:longint; var bufout:PByteBuffer; var lenout:longint):longint;
var
  ret:longint;
  buf:PByteBuffer;
  bytes_ret, b_ret:DWORD;
  msginfo:TULMessage;
begin
  if (bufin <> nil) and (lenin <> 0) then begin
    bufin^[0] := coninfo^.bcmd;
    inc(coninfo^.sn);
    bufin^[1] := ((coninfo^.sn) and $3F) + $40;
    bufin^[2] := lo(coninfo^.bsn);
    ret := send_command_wait(coninfo^.UL_fd, coninfo^.adr,
      coninfo^.cmd, coninfo^.outflg and (not UL_TAILMSG), bufin, lenin);
    if (ret<0) then begin
      Result := ret;
      exit;
    end;
  end;
  if true{(bufout <> nil)} then while true do begin
    ret := UL_fd_wait(coninfo^.UL_fd, coninfo^.timeout);
    if (ret <= 0) then begin
      if ret < 0 then
        Result := ret
      else
        Result := -1;
      exit;
    end;
    if (not DeviceIoControl(coninfo^.UL_fd, UL_ACCEPTMSG,
      nil, 0, @msginfo, sizeof(TULMessage), bytes_ret, nil)) then begin
      Result := -1;
      exit;
    end;
    if ( (msginfo.cmd <> coninfo^.bcmd) or
         (msginfo.sadr <> coninfo^.adr) or
         (msginfo.len < 3)
       )
    then begin
      DeviceIoControl(coninfo^.UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
        bytes_ret, nil);
      continue;
    end;

    GetMem(buf, msginfo.len);
    if buf = nil then begin
      Result := -1;
      exit;
    end;
    if ( not ReadFile(coninfo^.UL_fd, buf^, msginfo.len, b_ret, nil) ) then begin
      {free(buf);return -1;}
       FreeMem(buf);
       Result := -1;
       exit;
    end else
      ret := b_ret;
    DeviceIoControl(coninfo^.UL_fd, UL_FREEMSG, nil, 0, @ret, sizeof(ret),
      bytes_ret, nil);
    if((buf^[2] and $3F) = (coninfo^.sn and $3F)) then begin
      coninfo^.bsn := buf^[2];
      bufout := buf;
      lenout := msginfo.len;
      Result := 1;
      exit;
    end;
    FreeMem(buf);
  end;
  Result := 0;
end;

function ULoi_set_var(coninfo:PULoi_coninfo; oid:longint; val:pointer;
 size:longint):longint;
var
  bufout:PByteBuffer;
  bufin:PByteBuffer;
  lenout, lenin, ret:longint;
begin
  bufout := nil;
  lenin := 3+2+size+4;
  GetMem(bufin,lenin);
  if bufin = nil then begin
    Result := -1;
    exit;
  end;

  bufin^[3] := byte(oid);
  bufin^[4] := byte(oid shr 8);
  move(val^, bufin^[5], size);
  bufin[5+size+0] := ULOI_RDRQ;
  bufin[5+size+1] := 0;
  bufin[5+size+2] := 0;
  bufin[5+size+3] := 0;
  ret := ULoi_transfer(coninfo, bufin, lenin, bufout, lenout);
  FreeMem(bufin);
  if (ret<=0) then begin
    Result := -1;
    exit;
  end;
  if (bufout <> nil) then
    FreeMem(bufout);
  Result := 0;
end;

function ULoi_get_var(coninfo:PULoi_coninfo; oid:longint; val:pointer;
  size:longint):longint;
var
  bufout:PByteBuffer;
  bufin:PByteBuffer;
  lenout, lenin, ret:longint;
begin
  bufout := nil;
  lenin := 3+2+2+2;
  GetMem(bufin, lenin);
  if (bufin = nil) then begin
    Result := -1;
    exit;
  end;
  bufin^[3]:=ULOI_RDRQ;
  bufin^[4]:=0;
  bufin^[5]:= byte(oid);
  bufin^[6]:= byte(oid shr 8);
  bufin^[7]:= 0;
  bufin^[8]:= 0;
  ret := ULoi_transfer(coninfo, bufin, lenin, bufout, lenout);
  FreeMem(bufin);
  if(ret<=0) then begin
    Result := -1;
    exit;
  end;
  ret := -1;
  if((bufout^[3]=21) and (bufout^[4]=0) and (bufout^[5]= byte(oid))and
    (bufout[6] = byte(oid shr 8))) then begin
    move(bufout^[7], val^, size);
    ret := 0;
  end;
  if(bufout <> nil) then freemem(bufout);
  Result := ret;
end;

function ULoi_set_var_u2(coninfo:PULoi_coninfo; oid:longint; val:longint):longint;
var buf:array[0..1] of byte;
begin
  buf[0] := byte(val);
  buf[1] := byte(val shr 8);
  Result := ULoi_set_var(coninfo, oid, @buf, 2);
end;

function ULoi_get_var_u2(coninfo:PULoi_coninfo; oid:longint; var val:longint):longint;
var
  ret:longint;
  buf:array[0..1] of byte;
begin
  ret := ULoi_get_var(coninfo, oid, @buf, 2);
  if(ret >= 0) then
    val := buf[0]+(longint(buf[1]) shl 8);
  Result := ret;
end;

function wl_set_wlen(coninfo:PULoi_coninfo; wlen:longint):longint;
var ret, u: longint;
begin
  ret := ULoi_set_var_u2(coninfo, 204, wlen);
  if (ret < 0) then begin
    Result := ret;
    exit;
  end;
  while true do begin
    sleep(200);
    ret := ULoi_get_var_u2(coninfo, 204, u);
    if(ret < 0) then begin
      Result := ret;
      exit;
    end;
    if(u=$8000) then
      continue;
    if ((u and $8000) <> 0) or (u <> wlen) then begin
      Result := -1;
      exit;
    end;
    {Result := wlen;}
  end;
end;


function ULoi_send_cmd(coninfo:PULoi_coninfo; oid:longint):longint;
var
  buf:array[0..1] of byte;
begin
  Result := ULoi_set_var(coninfo,oid,@buf,0);
end;

procedure ULoi_close(coninfo:PULoi_coninfo);
begin
 CloseHandle(coninfo^.UL_fd);
 FreeMem(coninfo);
end;

function wl_scan(var Params:TScanParams):longint;
var
  ret:longint;
{  UL_fd:HANDLE;
  bytes_ret:DWORD;
  msginfo:TULMessage ;}
  coninfo:PULoi_coninfo;
  buf:array[0..9] of char;
  {struct timeval timeout;}
  wlen:longint;
  {aset: fd_set;
  abs:float;}
begin
  with Params do begin
    coninfo := ULoi_open(UL_dev_name, modULe, $10, 0, 10);
    if coninfo = nil then begin
      ShowMessage('wl_scan : ULan OI open failed');
      Result := -1;
      exit;
    end;
    try
      if time_co_fl <> 0 then begin
        ULoi_set_var_u2(coninfo, 208, time_co);
      end;
      if adc_chan_fl  <> 0 then begin
        ULoi_set_var_u2(coninfo,209,adc_chan);
      end;
      if lampctrl_fl <> 0 then begin
        ULoi_set_var_u2(coninfo,207,lampctrl);
      end;

      wlen := wl_begin;
      if wl_step = 0 then
         wl_end := wlen;
      if(
         ((wl_begin <= wl_end) and (wl_step >= 0)) or
         ((wl_begin >= wl_end) and (wl_step < 0))
         ) then
      while true do begin
        ret := wl_set_wlen(coninfo, wlen);
        if ret < 0 then
          ShowMessage('UL_set_wlen returned ' + IntToStr(ret));
        sleep(1000);
        if zero_fl <> 0 then begin
          ret := ULoi_send_cmd(coninfo,255);
          if ret < 0 then
           ShowMessage('ULoi_send_cmd returned ' + IntToStr(ret));
        end;
        ret := ULoi_get_var(coninfo,220, @buf, 4);
        if ret < 0 then
          ShowMessage('ULoi_get_var returned ' + IntToStr(ret));
        {printf("%d %f\n",wlen,IEEE4tofloat(buf));}

        if((wlen=wl_end) or (wl_step = 0)) then
          break;
        wlen := wlen + wl_step;
        if (
            ((wl_step > 0) and (wlen > wl_end)) or
            ((wl_step < 0) and (wlen < wl_end))
           ) then
          wlen := wl_end;
      end;
    finally
      ULoi_close(coninfo);
    end;
  end;
  Result := 0;
  exit;
end;

function ULoi_get_aoiddes(coninfo:PULoi_coninfo; list:longint; aoid:PChar;
  var name:shortstring; var typ:shortstring):longint;
var
  bufin : PByteBuffer;
  lenin: longint;
  bufout: PByteBuffer;
  lenout: longint;
  ret: longint;
  i,oid: longint;
  aoidlen: longint;
  p: PByteBuffer;
  pp:integer;

begin
  bufout := nil;
  aoidlen := StrLen(aoid);
  if (aoidlen > 100) then begin
    Result := -1;
    exit;
  end;
  GetMem(bufin, 7 + 1 + aoidlen + 2);
  if bufin = nil then begin
    Result := -1;
    exit;
  end;
  bufin^[3] := lo(LongRec(list).Lo);
  bufin^[4] := hi(LongRec(list).Lo);{(list shr 8);}
  bufin^[5] := ULOI_AOID;
  bufin^[6] := (ULOI_AOID shr 8);
  bufin^[7] := aoidlen;
  move(aoid^, bufin^[8], aoidlen);
  {memcpy(bufin+8,aoid,aoidlen);}
  bufin^[7+1+aoidlen] := 0;
  bufin^[7+1+aoidlen+1] := 0;
  lenin:= 7+1+aoidlen+2;
  ret := ULoi_transfer(coninfo, bufin, lenin, bufout, lenout);
  FreeMem(bufin);
  if (ret < 0) then begin
    Result := -1;
    exit;
  end;
  if (lenout < 3+2+2+1) then begin
    FreeMem(bufout);
    Result := -1;
    exit;
  end;
  oid := bufout^[5] + bufout^[6]* $100;
  {printf("     oid=%d",oid);}

  p := bufout;
  pp := 7;
  i := p^[pp];{*(p++);}
  {printf(" deslen=%d",i);}
  inc(pp);

  if (i <> 0) then begin
    i := p^[pp];
    inc(pp);
    if (i <> 0) then begin
      {printf(" name=\"");}
      name := '';
      while (i > 0) and (pp < lenout) {(i--&&(p<bufout+lenout))} do begin
        name := name + char(p^[pp]);
        dec(i);
        inc(pp);
        {putchar(*(p++));}
      end;
      {printf("\"");}
    end;

    {i=*(p++);}
    i := p^[pp];
    inc(pp);
    if(i <> 0) then begin
    { printf(" type=\"");}
      typ := '';
      while (i <> 0) and (pp < lenout) do begin
        typ := typ + chr(p^[pp]);
        dec(i);
        inc(pp);
      end;
      {while(i--&&(p<bufout+lenout)) putchar(*(p++));}
      {printf("\"");}
    end;
  end;
  {printf("\n");}
  FreeMem(bufout);
  Result := oid;
end;

function ULoi_get_oids(coninfo:PULoi_coninfo; list:longint;
  var oids_list:PLongintBuffer):longint;
var
  oids,toids{temp}: PLongintBuffer;
  oidsSize, toidsSize:longint;

  at_once: longint;
  bufin: array[0..8] of byte;
  lenin: longint;
  bufout: PByteBuffer;
  lenout: longint;
  last_oid: longint;
  oid_cnt: longint;
  cnt,i: longint;
  p: PByteBuffer;
  pp: longint;
  ret: longint;
begin
  oids := nil;
{  toids := nil;}
  oidsSize := 0;
{  toidsSize := 0;}
  at_once := 64;
  lenin := sizeof(bufin);
  bufout := nil;
  last_oid := 0;
  oid_cnt := 0;
{  pp := 0;}

  fillchar(bufin, sizeof(bufin), 0);
  {0,0,0,list,list>>8,0,0,at_once,at_once>>8}
  bufin[3] := lo(list);
  bufin[4] := hi(list);
  bufin[7] := lo(at_once);
  bufin[8] := hi(at_once);
  repeat
    bufin[5] := lo(last_oid);
    bufin[6] := hi(last_oid);
    ret := ULoi_transfer(coninfo, @bufin, lenin, bufout, lenout);
    if (ret < 0) then begin
      if (oids <> nil) then
        FreeMem(oids);
      {if bufout <> nil then
        FreeMem(bufout);? my addition}
      Result := -1;
      exit;
    end;
    cnt := lenout - 5 - 2;
    if (cnt <= 0) then begin
      if(oids <> nil) then
        FreeMem(oids);
      Result := -1;
      exit;
    end;
    cnt := cnt div 2;
    if (oids = nil) then begin
      oidsSize := (cnt + 1) * sizeof(longint);
      GetMem(oids, oidsSize);
      {oids := malloc((cnt+1)*sizeof(int));}
    end else begin
      toidsSize := (oid_cnt+cnt+1)*sizeof(longint);
      GetMem(toids, toidsSize);
      if toids <> nil then begin
        move(oids^, toids^, min(oidsSize, toidsSize));
        FreeMem(oids);
      end;
      {oids=realloc(oids,(oid_cnt+cnt+1)*sizeof(int));}
    end;

    p := bufout;
    pp := 5;

    i := cnt;
    if (last_oid <> 0) then begin
      if(last_oid <> (p^[pp] + p^[pp+1] * 256)) then begin
        freemem(oids);
        freemem(bufout);
        Result := -1;
        exit;
      end;
      inc(pp, 2);
      dec(i);
      {p+=2; i--;}
    end;
    while (i <> 0) do begin
      dec(i);
      last_oid := p^[pp] + p^[pp+1]*256;
      inc(pp, 2);
      if last_oid = 0 then
        break;
      oids^[oid_cnt] := last_oid;
      inc(oid_cnt);
    end;
    oids^[oid_cnt] := 0;
    FreeMem(bufout);
  until (cnt < at_once);
  {while(cnt>=at_once);}

  oids_list := oids;
  Result := oid_cnt;
end;

function uloi_get_oiddes(coninfo:PULoi_coninfo; list:longint; oid:longint;
  var name:shortstring; var typ:shortstring):longint;
var
  bufin: array[0..8]of byte;
  { [9]={0,0,0,list,list>>8,oid,oid>>8,0,0}
  lenin: longint;
  bufout: PByteBuffer;
  lenout: longint;
  ret: longint;
  i: longint;
  p: PByteBuffer;
  pp: longint;
begin
  lenin := sizeof(bufin);
  bufout := nil;
  fillchar(bufin, sizeof(bufin), 0);
  bufin[3] := lo(list);
  bufin[4] := hi(list);
  bufin[5] := lo(oid);
  bufin[6] := hi(oid);

  ret := ULoi_transfer(coninfo, @bufin, lenin, bufout, lenout);
  if(ret<0) then begin
    Result := -1;
    exit;
  end;
  if( lenout < 3+2+2+1) then begin
    if bufout <> nil then
      freemem(bufout);
    Result := -1;
    exit;
  end;
  {printf("     oid=%d",bufout[5]+bufout[6]*0x100);}
  p := bufout;
  pp := 7;
  i := p^[pp];
  inc(pp);
  {printf(" deslen=%d",i);}
  name := '';
  typ := '';
  if (i > 0) then begin
    i := p^[pp];
    inc(pp);
    if (i > 0) then begin
      { printf(" name=\"");}
      while (i > 0) and (pp < lenout) do begin
        name := name + chr(p^[pp]);
        inc(pp);
        dec(i);
      end;
      {while(i--&&(p<bufout+lenout)) putchar( *(p++));}
      { printf("\""); }
    end;
    i := p^[pp];
    inc(pp);
    if(i > 0) then begin
     { printf(" type=\""); }
     while (i > 0) and (pp < lenout) do begin
       dec(i);
       typ := typ + chr(p^[pp]);
       inc(pp);
     end;
     {while(i--&&(p<bufout+lenout)) putchar( *(p++));}
     { printf("\"");}
    end;
  end;
  {printf("\n");}
  freemem(bufout);
  Result := 0;
end;

{
function oi_var_test(var ScanParams:TScanParams; aoid:PChar;
  valin:PByteBuffer; var valout:PByteBuffer; var typ:PByteBuffer;
  AModULe:pointer):longint;
var
  ret:longint;
  oid:longint;
  oids:PLongintBuffer;
  val:longint;
  vallen:longint;
  i:longint;
  coninfo:PULoi_coninfo;
  list:longint;
  desc, typdesc: shortstring;
  hasTypDesc:array[0..MaxModULePropID-1]of boolean;
  Prop:TModULeProp;
begin
  fillChar(hasTypDesc, sizeof(hasTypDesc), 0);
  with ScanParams do begin
    vallen := 2;
    coninfo := uloi_open(UL_dev_name, module, $10,0,10);
    if coninfo = nil then begin
      ShowMessage('wl_scan : ULan OI open failed');
      Result := -1;
      exit;
    end;
    try
      if((aoid <> nil) and (aoid[0] <> #0)) then
      begin
        oid := StrToInt(aoid);
        if oid = 0 then begin
          if oi_var_rd <> 0 then
            list := ULOI_DOIO
          else
            list := ULOI_DOII;
          ret := ULoi_get_aoiddes(coninfo, list, aoid, var_desc, var_typ);
          if (ret < 0) then begin
            ShowMessage('oi_var_test : ULoi_get_aoiddes returned ' + IntToStr(ret));
            Result := -1;
            exit;
          end;
          oid := ret;
        end;
        if (valout = nil) and (oi_var_rd = 0) then begin
          if (valin <> nil) and (valin^[0] <> 0) then begin
            val := StrToInt(PChar(valin));
          end else begin
            vallen :=0;
          end;
          ret := ULoi_set_var(coninfo, oid, @val, vallen);
          if (ret < 0) then begin
            ShowMessage('oi_var_test : ULoi_set_var failed');
            Result := -1;
            exit;
          end;
        end else begin
          ret := ULoi_get_var(coninfo,  oid, @val, vallen);
          if (ret < 0) then begin
            ShowMessage('oi_var_test : ULoi_get_var failed');
            Result := -1;
            exit;
          end;
          if (val and $8000) <> 0 then
            val := val or (not $ffff)
          else
            val := val and $ffff;
          var_value := IntToStr(val);
        end;
      end else begin
        if AModULe = nil then begin
          ShowMessage('oi_var_test : AModULe = nil');
          Result := -1;
          exit;
        end;
        ret := ULoi_get_oids(coninfo, ULOI_QOII, oids);
        if (ret < 0) then begin
          ShowMessage('oi_var_test : ULoi_get_oids returned ' + IntToStr(ret));
          Result := -1;
          exit;
        end;
        try
          for i := 0 to ret - 1 do begin
            typdesc := '';
            hasTypDesc[oids^[i]] := true;
            ULoi_get_oiddes(coninfo,ULOI_DOII,oids^[i], desc, typdesc);
            if typdesc <> '' then begin
              if ModULeFindOrAddProp(TModULe(AModULe), oids^[i], Prop) then begin
                Prop.PropID := oids^[i];
                Prop.PropDesc := desc;
                Prop.TypeDesc := typdesc;
                Prop.Flags := Prop.Flags or pfWrite;
              end;
            end;
          end;
        finally
          FreeMem(oids);
        end;
        ret := ULoi_get_oids(coninfo, ULOI_QOIO, oids);
        if(ret < 0) then begin
          ShowMessage('oi_var_test : ULoi_get_oids returned ' + IntToStr(ret));
          Result := -1;
          exit;
        end;
        try
          for i := 0 to ret - 1 do begin
            typdesc := '';
            ULoi_get_oiddes(coninfo, ULOI_DOII, oids^[i], desc, typdesc);
            if hasTypDesc[oids^[i]] or (typdesc <> '') then begin
              if ModULeFindOrAddProp(TModULe(AModULe), oids^[i], Prop) then begin
                Prop.PropDesc := desc;
                Prop.TypeDesc := typdesc;
                Prop.Flags := Prop.Flags or pfRead;
              end;
            end;
          end;
        finally
          FreeMem(oids);
        end;
      end;
    finally
      ULoi_close(coninfo);
    end;
  end;
  Result := 0;
end;
}
*)

