3
votes

I need a way to use the WMI to find the name of a modem (or other device) which is currently attatched to a COM port which I already know.

For example lets say I have already extracted that the device I want is on COM port 3 and I also know it is a modem, how can I find the name of the modem associated with that COM port.

Currently I have code using Win32_PnPEntity which can extract a list of pnp devices with either modem or COM in the name but unfortunatley when I return the COM devices they do not carry the modem name and when I extract modem device they do not associate with a COM port (so if I have two modems attached I do not know which is in COM port 3). I have also found a Win32_SerialPort function but this does not return all devices attatched to my computer via serial ports.

const   wbemFlagForwardOnly = $00000020;

var

    FSWbemLocator : OLEVariant;
    FWMIService   : OLEVariant;
    FWbemObjectSet: OLEVariant;
    FWbemObject   : OLEVariant;
    oEnum         : IEnumvariant;
    iValue        : LongWord;
    ts            : String;

begin;

    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\cimv2', '', '');

//This WMI service checks for plug and play devices
FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_PnPEntity','WQL',wbemFlagForwardOnly);


//This WMI service which I didn't use checks for serial ports and what is on them - currently not displaying sufficient information}
//FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM  Win32_SerialPort','WQL',wbemFlagForwardOnly);

oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;

while oEnum.Next(1, FWbemObject, iValue) = 0 do
    begin
        if not VarIsNull(FWbemObject.name) then
            begin
                ts:= String(FWbemObject.name);

                if pos('(COM',ts)<>0 then
                    pnpForm.listbox1.items.add(ts);
            end;

        FWbemObject:=Unassigned;
    end;
end;
1
Maybe the answer can be found here: How to enumerate all installed usb modem using Windows API. A WMI solution is given as well.LU RD
There is an AT Command for that. Search on Google for it much simpler than WMIopc0de
COM port based devices are not Plug an Play and are not detectable by design. You can even have multiple standard modems installed and assigned to the same COM port number. These devices would be also be listed as multiple in the Device Manager. The reason why a USB based COM port device is detectable is because both device and port is bound to a single device and have the same name.Jay
This is really tricky stuff. We don't know if this is a directly attached com port (ie UART 16550) on the motherboard, or PCI, or USB serial port, and so on. USB-modems are easy to enumerate, but Modems that are non-USB are simply a configuration property of Windows control panel icon for TAPI, and are probably not WMI queryable nor otherwise WinAPI enumerable. Some modems exist as a TAPI entity without being otherwise visible.Warren P
Try the Win32_POTSModem WMI class and the AttachedTo property.RRUZ

1 Answers

4
votes

...For example lets say I have already extracted that the device I want is on COM port 3 and I also know it is a modem, how can I find the name of the modem associated with that COM port.

You can use the AttachedTo property of the Win32_POTSModem WMI class to get the Port to which the modem is attached.

Try this sample

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;


function  GetConnectedModem(const PortName : string):string;
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin
  Result:='';
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery(Format('SELECT Name FROM Win32_POTSModem Where AttachedTo="%s"',[PortName]),'WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    Result:=FWbemObject.Name;
    FWbemObject:=Unassigned;
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      Writeln(GetConnectedModem('COM1'));
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); 
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.